【二分+最短路】UVA 11478 Halum

差分约束系统

二分 + 最短路

  1 //Izayoi bless me
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<cctype>
  7 #include<cmath>
  8 #include<limits.h>
  9 #include<iomanip>
 10 #include<cstring>
 11 #include<fstream>
 12 #include<string>
 13 #include<queue>
 14 #include<stack>
 15 #include<set>
 16 #include<map>
 17 #include<vector>
 18 using namespace std;
 19 const double pi = 4.0 * atan(1.0);
 20 typedef signed long long LL;
 21 #define clr(x) memset(x,0,sizeof(x))
 22 #define clro(x) memset(x,-1,sizeof(x))
 23 typedef pair<int,int> pii;
 24 const int inf = 99999999;
 25 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
 26 #define sf scanf
 27 #define pf printf
 28 const int maxn = 555;
 29 const int maxm = 3333;
 30 struct Edge{
 31     int v,nex,len;
 32 }edges[maxm];
 33 int tot;
 34 int head[maxn],dis[maxn],in[maxn];
 35 bool vis[maxn];
 36 int n,m;
 37 void init(){
 38     tot = 0;
 39     clro(head);
 40 }
 41 void addedge( int u, int v, int c){
 42     Edge e;
 43     e.v = v, e.len = c;
 44     e.nex = head[u];
 45     edges[tot] = e;
 46     head[u] = tot++;
 47 }
 48 void input(){
 49     int a,b,c;
 50     forint i=0; i<m; ++i){
 51         sf("%d%d%d",&a,&b,&c);
 52         addedge(a,b,c);
 53     }
 54 }
 55 bool spfa(){
 56     clr(in); clr(dis); clr(vis);
 57     queue<int>que;
 58     forint i=1; i<=n; ++i){ 
 59         que.push(i);
 60     }
 61     int x;
 62     while( !que.empty() ){
 63         x = que.front(); que.pop();
 64         vis[x] = false;
 65         forint i=head[x]; ~i; i = edges[i].nex){
 66             Edge &e = edges[i];
 67             if( dis[e.v] > dis[x] + e.len ){
 68                 dis[e.v] = dis[x] + e.len;
 69                 if( !vis[e.v] ){
 70                     vis[e.v] = true;
 71                     if( ++in[e.v] > n ) return true;
 72                     que.push(e.v);
 73                 }
 74             }
 75         }
 76     }
 77     return false;
 78 }
 79 bool find( int x){
 80     bool f;
 81     forint i=0; i<tot; ++i) edges[i].len -=x;
 82     f = spfa();
 83     forint i=0; i<tot; ++i) edges[i].len +=x;
 84     return f;
 85 }
 86 void doit(){
 87     if( find(0) ){//你们懂的
 88         puts("No Solution");
 89         return;
 90     }
 91     if( !find(10001) ){//不解释了
 92         puts("Infinite");
 93         return;
 94     }
 95     int l=1,r=10000,mid;
 96     while( l < r ){//二分查找求下界
 97         mid = (l+r)>>1;
 98         if( find(mid) ) r = mid;
 99         else l = mid+1;
100     }
101     --l;//所求出的x是形成副环的x,即最小的不行的答案,所以-1,成为最大的可行的答案
102     if( l == 0 ){//没有找到可行答案
103         puts("No Solution");
104         return;
105     }
106     pf("%d\n",l);
107     
108 }
109 int main(){
110     while( sf("%d%d",&n,&m) == 2 ){
111         init();
112         input();
113         doit();
114     }
115     return 0;
116 }

 

posted @ 2012-12-24 22:57  masterhe  阅读(225)  评论(0)    收藏  举报