poj3169&poj1201
这两题是经典的差分约束系统,稍微学习一下就可以指导如何转化为差分约束,3169里可以看到明确的其源点1,所以求解的是从1出发终点为n的最短路,而1201则不太明显(我的代码是将其转化为最长路),但是要注意min,max在代码中的意义,和dist的定义,详情可以参考论文《数与图的完美结合--差分约束系统》,我想说的是我们要求接的是dist[max]-dist[min]的最大值,那么将dist[min]置为0然后求其到max的最大值不是更方便。
3169
View Code
1 #include <stdio.h>
2 #include <queue>
3 #include <string.h>
4 using std::queue;
5 #define MAXN 10010
6 #define INF (1<<29)
7 struct node
8 {
9 int d,c,next;
10 }edge[2*MAXN];
11 int head[MAXN],p;
12 int dist[MAXN],cnt[MAXN];
13 int n,ml,md,max;
14 bool v[MAXN];
15 queue <int> q;
16 void add(int a,int b,int c)
17 {
18 edge[p].d=b;
19 edge[p].c=c;
20 edge[p].next=head[a];
21 head[a]=p++;
22 }
23 bool spfa()
24 {
25 dist[1]=0;
26 v[1]=true;
27 q.push(1);
28 ++cnt[1];
29 while(!q.empty())
30 {
31 int k=q.front();
32 q.pop();
33 v[k]=false;
34 for(p=head[k];p!=-1;p=edge[p].next)
35 if(dist[edge[p].d]>dist[k]+edge[p].c)
36 {
37 dist[edge[p].d]=dist[k]+edge[p].c;
38 if(!v[edge[p].d])
39 {
40 if(++cnt[edge[p].d]>n)
41 return false;
42 v[edge[p].d]=true;
43 q.push(edge[p].d);
44 }
45 }
46 }
47 return true;
48 }
49 int main()
50 {
51 //freopen("test.txt","r",stdin);
52 while(scanf("%d %d %d",&n,&ml,&md)==3)
53 {
54 memset(head,-1,sizeof(head));
55 memset(v,false,sizeof(v));
56 p=0;
57 for(int i=0,a,b,c;i<ml;++i)
58 {
59 scanf("%d %d %d",&a,&b,&c);
60 add(a,b,c);
61 }
62 for(int i=0,a,b,c;i<md;++i)
63 {
64 scanf("%d %d %d",&a,&b,&c);
65 add(b,a,-c);
66 }
67 for(int i=1;i<n;++i)
68 add(i+1,i,0);
69 for(int i=1;i<=n;dist[i++]=INF);
70 if(!spfa())
71 printf("-1\n");
72 else if(dist[n]-dist[0]>=INF)
73 printf("-2\n");
74 else
75 printf("%d\n",dist[n]-dist[0]);
76 }
77 return 0;
78 }
1201
View Code
1 #include <stdio.h>
2 #include <string.h>
3 #include <queue>
4 using std::queue;
5 #define INF (1<<29)
6 #define MAXN 50010
7 #define MAX(a,b) ((a)>(b)?(a):(b))
8 #define MIN(a,b) ((a)<(b)?(a):(b))
9 struct node
10 {
11 int d,c,next;
12 }edge[3*MAXN];
13 int head[MAXN],p;
14 bool v[MAXN];
15 int dist[MAXN];
16 int num,max,min;
17 queue <int> q;
18 void add(int a,int b,int c)
19 {
20 edge[p].d=b;
21 edge[p].c=c;
22 edge[p].next=head[a];
23 head[a]=p++;
24 }
25 void spfa()
26 {
27 v[min]=true;
28 q.push(min);
29 dist[min]=0;
30 int k;
31 while(!q.empty())
32 {
33 k=q.front();
34 q.pop();
35 v[k]=false;
36 for(int i=head[k];i!=-1;i=edge[i].next)
37 if(dist[edge[i].d]<dist[k]+edge[i].c)
38 {
39 dist[edge[i].d]=dist[k]+edge[i].c;
40 if(!v[edge[i].d])
41 {
42 v[edge[i].d]=true;
43 q.push(edge[i].d);
44 }
45 }
46 }
47 }
48 int main()
49 {
50 //freopen("test.txt","r",stdin);
51 while(scanf("%d",&num)!=EOF)
52 {
53 memset(head,-1,sizeof(head));
54 memset(v,false,sizeof(v));
55 max=p=0;
56 min=INF;
57 for(int i=0,a,b,c;i<num;++i)
58 {
59 scanf("%d %d %d",&a,&b,&c);
60 ++b;
61 max=MAX(max,b);
62 min=MIN(min,a);
63 add(a,b,c);
64 }
65 for(int i=min;i<max;++i)
66 {
67 add(i,i+1,0);
68 add(i+1,i,-1);
69 }
70 for(int i=min;i<=max;dist[i++]=-INF);
71 spfa();
72 printf("%d\n",dist[max]-dist[min]);
73 }
74 return 0;
75 }