poj-1752 Advertisement **

  1 /*
2 * 很自然的 差分约束系统, 没具体写, 转一个。。
3 *
4 *
5 *  http://www.cnblogs.com/ihainan/archive/2011/07/23/2114884.html
6 * 解题思路:由题可得如下约束条件:
7 *  如果 b - a >= k
8 * S[b] - S[a] >= k
9 *   否则 S[b] - S[a] >= dis(a, b)
10 * S[b] - S[a] <= dis(a, b)
11 *  同时 0 <= S[i] - S[i - 1] <= 1
12 *
13 * 由约束条件可建图,spfa求最长路
14 *
15 * STL里面的东西最好还是不用,写出来的spfa甚至比bellman还慢!!!
16 */
17
18 #include<stdio.h>
19 #include<string.h>
20 #define N 1200
21 #define maxint 0xfffffff
22 #define num 40000
23 void init(), spfa(), print(), addedge(int, int, int);
24 struct EDGE{
25 int x, y, w, next;
26 }e[5 * num];
27 int head[3 * num], n, k, m = 0, dis[3 * num], vis[3 * num], ans = 0, minnum = maxint, maxnum = -maxint, queue[num * 300];
28 int main()
29 {
30 init();
31 spfa();
32 print();
33 return 0;
34 }
35 void init()
36 {
37 int i, j, a, b, c, ch;
38 memset(head, -1, sizeof(head));
39 memset(dis, 0, sizeof(dis));
40 scanf("%d %d", &k, &n);
41 for(i = 1; i <= n; ++i){
42 scanf("%d %d", &a, &b);
43 if(a > b){
44 ch = a;
45 a = b;
46 b = ch;
47 }
48 a += num - 1;
49 b += num;
50 minnum = minnum < a ? minnum : a;
51 maxnum = maxnum > b ? maxnum : b;
52 c = b - a;
53 if(c < k){
54 addedge(a, b, c);
55 addedge(b, a, -c);
56 }
57 else
58 addedge(a, b, k);
59 }
60 }
61 void addedge(int x, int y, int w)
62 {
63 ++m;
64 e[m].x = x;
65 e[m].y = y;
66 e[m].w = w;
67 e[m].next = head[x];
68 head[x] = m;
69 }
70
71 void spfa()
72 {
73 int i, j, x, y, tail = 0, front = 0;
74 for(i = minnum; i <= maxnum; ++i){
75 if(i != 0){
76 queue[++tail] = i;
77 addedge(i, i + 1, 0);
78 addedge(i + 1, i, -1);
79 }
80 dis[i] = -maxint;
81 vis[i] = 0;
82 }
83 dis[minnum] = 0;
84 vis[minnum] = 1;
85 while(front < tail){
86 x = queue[++front];
87 vis[x] = 0;
88 for(i = head[x]; i != -1; i = e[i].next){
89 y = e[i].y;
90 if(dis[x] + e[i].w > dis[y]){
91 dis[y] = e[i].w + dis[x];
92 if(!vis[y]){
93 vis[y] = 1;
94 queue[++tail] = y;
95 }
96 }
97 }
98 }
99 }
100
101 void print()
102 {
103 int i;
104 printf("%d\n", dis[maxnum]);
105 for(i = minnum; i <= maxnum; ++i)
106 if(dis[i] - dis[i - 1] == 1 )
107 printf("%d\n", i - num);
108 }

你可能感兴趣的:(poj)