【二分+最短路】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 for( int 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 for( int 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 for( int 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 for( int i=0; i<tot; ++i) edges[i].len -=x;
82 f = spfa();
83 for( int 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 }
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 for( int 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 for( int 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 for( int 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 for( int i=0; i<tot; ++i) edges[i].len -=x;
82 f = spfa();
83 for( int 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 }


浙公网安备 33010602011771号