zoukankan      html  css  js  c++  java
  • pku 2983 差分约束系统判断

    该题有两种输入

    1、P A B X 。表示A到B的距离点明了为X:A-B==X,等价于A-B<=X&& A-B>=X (B-A<=-X)。于是得到两条边(A,B,X)和(B,A,-X)。

    以前我很纠结A-B<=X是建成(A,B,X)呢,还是(B,A,X)呢,今天我实践了一下,发现都无关紧要,关键是接下来的所有边,你都得按照这个顺序来就是了!

    2、V A B 。表示A到B的距离最少为1:即A-B>=1,等价于B-A<=-1,得到边(B,A,-1)。

    最后再从原点向所有点引一条边权为0的边(S,i,0) i=1->n。

    图建好了,用SPFA求解即可,如果不存在负环的话,则一定有解!

    这题属于水题,不过带给了我一下收获:

    1、A,B的距离恒为X的时候,可以将A-B==X 转化为A-B>=X&& A-B<=X

    2、A-B<=X的时候不必纠结建A->B 还是B->A,只需要保证接下来的所有边都按某一个规则就是了

    3、SPFA判断负环的条件是cut[X]>n,其中n为图中所有的节点数。

    #include<iostream>
    #include<string>
    #include<queue>
    using namespace std;
    #define inf 0xfffffff
    
    typedef struct node
    {
    	int v;
    	int w;
    	struct node *next;
    }node;
    
    node *link[1005];
    node edge[205000];
    int num;
    
    void add(int u,int v,int w)
    {
    	edge[num].v=v;
    	edge[num].w=w;
    	edge[num].next=link[u];
    	link[u]=edge+num++;
    }
    
    int n,m;
    int v[1005],dist[1005],cut[1005];
    
    int spfa()
    {
    	queue<int>Q;
    	for(int i=0;i<=n;i++)
    	{
    		v[i]=0;
    		dist[i]=inf;
    		cut[i]=0;
    	}
    	v[0]=1;
    	dist[0]=0;
    	Q.push(0);
    	cut[0]=1;
    	while(!Q.empty())
    	{
    		int x=Q.front();
    		Q.pop();
    		v[x]=0;
    		for(node *p=link[x];p;p=p->next)
    		{
    			if(dist[p->v]>dist[x]+p->w)
    			{
    				dist[p->v]=dist[x]+p->w;
    				if(!v[p->v])
    				{
    					v[p->v]=1;
    					cut[p->v]++;
    					if(cut[p->v]>n+1) //还有原点算一个点
    						return 0;
    					Q.push(p->v);
    				}
    			}
    		}
    	}
    	return 1;
    }
    
    int main()
    {
    	int i,a,b,w;
    	char c;
    	freopen("D:\\in.txt","r",stdin);
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		scanf("%*c");
    		memset(link,0,sizeof(link));
    		num=0;
    		for(i=0;i<m;i++)
    		{
    			scanf("%c",&c);
    			if(c=='P')
    			{
    				scanf("%d%d%d",&a,&b,&w);
    				add(a,b,w);
    				add(b,a,-w);
    			}
    			else
    			{
    				scanf("%d%d",&a,&b);
    				add(b,a,-1);
    			}
    			scanf("%*c");
    		}
    		for(i=1;i<=n;i++)
    		{
    			add(0,i,0);
    		}
    		if(spfa())
    		{
    			printf("Reliable\n");
    		}
    		else
    		{
    			printf("Unreliable\n");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    FZU 2150 Fire Game
    POJ 3414 Pots
    POJ 3087 Shuffle'm Up
    POJ 3126 Prime Path
    POJ 1426 Find The Multiple
    POJ 3278 Catch That Cow
    字符数组
    HDU 1238 Substing
    欧几里德和扩展欧几里德详解 以及例题CodeForces 7C
    Codeforces 591B Rebranding
  • 原文地址:https://www.cnblogs.com/ka200812/p/2125624.html
Copyright © 2011-2022 走看看