uva 11478 最短路徑問題(負環,差分約束系統)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2473
You are given a directed graph G(V,E) with a set of vertices and edges. Each edge (i,j) that connects some vertex i to vertex j has an integer cost associated with that edge. As an example of that operation, consider graph G that has three vertices named (1, 2, 3) and two edges. Edge (1, 2) has cost -1, and edge (2,3) has cost 1. The operation Halum(2,-3) operates on edges entering and leaving vertex 2. Thus, edge (1, 2) gets cost -1-(-3)=2 and the edge (2, 3) gets cost 1 + (-3) = -2. Your goal is to apply the Halum function to a graph, potentially repeatedly, until every edge in the graph has at least a certain cost that is greater than zero. You have to maximize this cost.
|
||||
Input | ||||
Two space-separated integers per case: V(V≤500) and E(E≤2700). E lines follow. Each line represents a directed edge using three space-separated integers (u, v, d). Absolute value of cost can be at most 10000. |
||||
Output | ||||
If the problem is solvable, then print the maximum possible value. If there is no such solution print “No Solution”. If the value can be arbitrary large print “Infinite” |
||||
Sample Input | Sample Output | |||
2 1
|
Infinite |
分析:注意,不同的操作互不影響,因此可以按任意的順序實施這些操作。另外對於同一個節點的多次操作也可合併,因此可以令sum(u),為作用於節點u之上的所有d之和,這樣,本題的目標就是確定所有的sum(u),使得操作之後的所有的邊權的最小值儘量大。
“最小值最大”又讓我們想到了二分答案。二分答案x後,問題轉化為是否可以讓操作完畢後的每條邊的權值均不小於x。對於邊a-》b,不難發現操作完畢之後它的權值為w(a,b)+sum(a)-sum(b),一次每條邊都可以列出一個不等式w(a,b)+sum(a)-sum(b)>=x,移項得sum(b)-sum(a)<=w(a,b)-x;這樣我們實際上就得到了一個差分約束系統。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
using namespace std;
const int INF=9999999999;
const int N=503;
struct note
{
int to,w,next;
}edge[N*N];
int head[N],ip,m,n;
int cnt[N],dis[N],in[N];
void addedge(int u,int v,int w)
{
edge[ip].to=v,edge[ip].w=w,edge[ip].next=head[u],head[u]=ip++;
}
void init()
{
memset(head,-1,sizeof(head));
ip=0;
}
bool spfa(int s)
{
queue<int> q;
for(int i=0;i<=n;i++)
{
dis[i]=INF;
in[i]=false;
cnt[i]=0;
}
dis[s]=0;
in[s]=true;
cnt[s]++;
q.push(s);
while(!q.empty())
{
int u=q.front();
in[u]=false;
q.pop();
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[u]+edge[i].w<dis[v])
{
dis[v]=dis[u]+edge[i].w;
if(!in[v])
{
q.push(v);
in[v]=true;
if(++cnt[v]>=n+1)
return false;
}
}
}
}
return true;
}
bool jud(int x)
{
bool flag=1;
for(int i=0;i<=n;i++)
for(int j=head[i];j!=-1;j=edge[j].next)
edge[j].w-=x;
if(!spfa(0)) flag=0;
for(int i=0;i<=n;i++)
for(int j=head[i];j!=-1;j=edge[j].next)
edge[j].w+=x;
return flag;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
int u,v,w;
int maxx=-INF;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
maxx=max(maxx,w);
}
for(int i=1;i<=n;i++)
addedge(0,i,0);
if(jud(maxx+1)) printf("Infinite\n");
else if(!jud(1))printf("No Solution\n");
else
{
int mid,l=1,r=maxx,ans=1;
while(l<=r)
{
mid=(l+r)>>1;
if(jud(mid))//小的滿足再判斷大的是否可以,因為要取大的
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
printf("%d\n",ans);
}
}
return 0;
}
相關文章
- 差分約束系統+SPFA/Bellman判斷負權迴路+uva515
- 淺談差分約束系統
- 差分約束系統詳解
- 差分約束
- POJ 2983-Is the Information Reliable?(差分約束系統)ORM
- POJ 1364-King(差分約束系統)
- 演算法學習之路|差分約束系統演算法
- 差分約束系統+poj1201
- POJ 3169-Layout(差分約束系統-入門裸題)
- 最短路徑問題
- 差分約束學習筆記筆記
- POJ 3169(Bellman-Ford演算法,差分約束系統)演算法
- POJ 3159-Candies(差分約束系統-SPFA+鄰接表)
- 演算法:最短路徑問題演算法
- [演算法學習筆記] 差分約束演算法筆記
- Day2 尤拉路,拓撲排序和差分約束排序
- 最短路徑問題 (dijkstra演算法)演算法
- (10)邏輯綜合新增約束(環境約束)
- 使用A*演算法解迷宮最短路徑問題演算法
- 圖論最短路徑問題與matlab實現圖論Matlab
- 分散式資料庫環境中,外來鍵約束的問題??分散式資料庫
- 無順序約束的字串匹配問題字串匹配
- [最短路徑問題]Dijkstra演算法(含還原具體路徑)演算法
- Javaweb-約束的分類JavaWeb
- 最短路徑問題,BFS,408方向,思路與實現分析
- HDU3790 最短路徑問題【Dijkstra演算法】演算法
- 常見問題--表的約束initially immediate 理解
- 【SQL】15 SQL 約束(Constraints)、NOT NULL 約束、UNIQUE 約束、PRIMARY KEY 約束、FOREIGN KEY 約束、CHECK 約束、DEFAULT約束SQLAINull
- 時序分析:基礎知識整理(三)差分轉單端的約束等
- 最優化之無約束優化優化
- python實現Dijkstra演算法之 最短路徑問題Python演算法
- iOS Autolayout 修改約束優先順序崩潰問題iOS
- mysql資料庫匯入外來鍵約束問題MySql資料庫
- 遷移後處理外來鍵約束的問題
- 利用函式索引解決複雜的約束問題函式索引
- Javaweb-約束-外來鍵約束JavaWeb
- CF79D Password (差分+狀壓 dp+最短路/bfs)
- 資料庫系統之實體完整性約束資料庫