Is the Information Reliable?(差分约束系统)

http://poj.org/problem?id=2983

题意:给出M条信息,判断这些信息的正确性。(1)V A B :表示A,B之间的距离>=1; (2)P A B X :表示A B之间的距离为x。

思路:dis[i]表示i到原点的距离,由(1)知 dis[A]<=dis[B]-1 即B->A之间有一条边,权值为-1;由(2)知: dis[A]<=dis[B]-x && dis[B] <= dis[A]+x,即A->B的权值为-x,B->A的权值为x。增加一个超级源点,与所有的点相连且权值为0.建图,spfa判断是否有负环(即判断进站次数,若大于点数则存在负环)。若存在负环则信息为假,否则为真。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <queue>
 4 using namespace std;
 5 const int N=1000010;
 6 const int INF=1<<28;
 7 int head[1010],vis[1010];
 8 int dis[N],num[1010];
 9 int cnt,n;
10 
11 struct node
12 {
13     int u,v,w;
14     int next;
15 } edge[N];
16 void init()
17 {
18     cnt = 0;
19     memset(head,-1,sizeof(head));
20     memset(vis,0,sizeof(vis));
21     memset(num,0,sizeof(num));
22 }
23 void add(int u,int v,int w)
24 {
25     edge[cnt].u = u;
26     edge[cnt].v = v;
27     edge[cnt].w = w;
28     edge[cnt].next = head[u];
29     head[u] = cnt++;
30 }
31 int spfa()
32 {
33     queue<int>q;
34     for (int i = 0; i <= n; i ++)
35         dis[i] = INF;
36     dis[0] = 0;
37     q.push(0);
38     vis[0] = 1;
39     while(!q.empty())
40     {
41         int u = q.front();
42         vis[u] = 0;
43         q.pop();
44         for (int j = head[u]; j!=-1; j=edge[j].next)
45         {
46             int v = edge[j].v;
47             int w = edge[j].w;
48             if (dis[v] > dis[u]+w)
49             {
50                 dis[v] = dis[u]+w;
51                 if (!vis[v])
52                 {
53                     q.push(v);
54                     vis[v] = 1;
55                     ++num[v];
56                     if (num[v] > n)
57                         return 0;
58                 }
59             }
60         }
61     }
62     return 1;
63 }
64 int main()
65 {
66     int m,u,v,w;
67     char s[3];
68     while(~scanf("%d%d",&n,&m))
69     {
70         init();
71         for (int i = 0; i <= n; i++)
72             add(0,i,0);
73         for (int i = 0; i < m; i++)
74         {
75             scanf("%s",s);
76             if (s[0]=='P')
77             {
78                 scanf("%d %d %d",&u,&v,&w);
79                 add(u,v,w);
80                 add(v,u,-w);
81             }
82             if (s[0]=='V')
83             {
84                 scanf("%d %d",&u,&v);
85                 add(v,u,-1);
86             }
87         }
88         if (spfa())
89             printf("Reliable\n");
90         else
91             printf("Unreliable\n");
92     }
93     return 0;
94 }
View Code

 

posted @ 2014-02-20 21:28  N_ll  阅读(320)  评论(0编辑  收藏  举报