poj 2983 Is the Information Reliable? (差分约束 spfa)

来源:互联网 发布:时时彩组号软件 编辑:程序博客网 时间:2024/05/17 02:40
/*    先不说什么。这个题目晦涩难懂,还有一种可能是我英语太渣了。 = =    差分约束条件题目的难点是“怎么找到问题的约束条件”。    输入边的信息有两种情况。P 和 V。    P i j b 表示 xi - xj = b >>>>   xi - xj <= b && xi - xj >= b (即 xj - xi <= -b)    V 表示边长不确定  xi - xj >= 1  >>>>   xj - xi <= -1;    好了,列出方程后建图,spfa即可    先要建立一个源点,源点到其他顶点之间的距离全部是0,然后用spfa判断是否存在负环        */#include<iostream>#include<cstring>#include<queue>#include<cstdio>using namespace std;const int N =  1010;const int M = 100010;const int inf = 0x3f3f3f3f;typedef struct{    int next,w,e;} Node;Node edge[M*3];int head[1010];int inqueue[1010];bool vis[1010];int num_edge;int dis[1010];int n,m;void addedge(int u,int v,int w){    edge[num_edge].e = v;    edge[num_edge].w = w;    edge[num_edge].next = head[u];    head[u] = num_edge++;}bool spfa(int start)/*spfa 队列*/{    memset(vis,false,sizeof(vis));    memset(inqueue,0,sizeof(inqueue));    for(int i = 0 ; i <= n ; i++)    {        dis[i] = inf;    }    queue<int>q;    vis[start] = true;    q.push(start);    dis[start] = 0;    while(!q.empty())    {        int cur = q.front();        q.pop();        vis[cur] = false;        inqueue[cur]++;        if(inqueue[cur] > n)        {            return false;        }        for(int i = head[cur] ; i != -1 ; i = edge[i].next)        {            int x = edge[i].e;            if(dis[x] > dis[cur] + edge[i].w)            {                dis[x] = dis[cur] + edge[i].w;                if(!vis[x])                {                    vis[x] = true;                    q.push(x);                }            }        }    }    return true;}int main(){    while(scanf("%d %d",&n,&m) != EOF )    {        memset(head,-1,sizeof(head));        num_edge = 0;        char s[5];        int u,v,w;        for(int i = 0 ; i < m ; i++)        {            scanf("%s",s);            if(s[0] == 'P')            {                scanf("%d %d %d",&u,&v,&w);                addedge(u,v,w);                addedge(v,u,-w);            }            else if(s[0] == 'V')            {                scanf("%d %d",&u,&v);                addedge(v,u,-1);            }        }        for(int i = 1; i <= n ; i++)        {            addedge(0,i,0);        }        bool flag = spfa(0);        if(flag )        {            printf("Reliable\n");        }        else        {            printf("Unreliable\n");        }    }    return 0;}