首页 > 技术文章 > 洛谷P1993 小 K 的农场(查分约束)

yanlifneg 2016-09-02 17:38 原文

/*
加深一下对查分约束的理解
建图的时候为了保证所有点联通 虚拟一个点
它与所有点相连 权值为0
然后跑SPFA判负环
这题好像要写dfs的SPFA 要不超时
比较懒 改了改重复进队的条件~ 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 40010
using namespace std;
int n,m,num,head[maxn],dis[maxn],f[maxn],c[maxn],falg;
struct node{
    int v,t,pre;
}e[maxn];
queue<int>q;
void Add(int from,int to,int dis){
    num++;e[num].v=to;
    e[num].t=dis;
    e[num].pre=head[from];
    head[from]=num;
}
void SPFA(){
    memset(dis,127/3,sizeof(dis));
    f[n+1]=1;dis[n+1]=0;
    q.push(n+1);c[n+1]++;
    while(!q.empty()){
        int k=q.front();q.pop();
        if(c[k]>n){
            falg=1;break;
        }
        f[k]=0;
        for(int i=head[k];i;i=e[i].pre){
            int v=e[i].v;
            if(dis[v]>dis[k]+e[i].t){
                dis[v]=dis[k]+e[i].t;
                if(f[v]==0){
                    f[v]=1;c[v]++;
                    q.push(v);
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    int w,x,y,z;
    for(int i=1;i<=m;i++){
        scanf("%d",&w);
        if(w==1){
            scanf("%d%d%d",&x,&y,&z);
            Add(y,x,-z);
        }
        if(w==2){
            scanf("%d%d%d",&x,&y,&z);
            Add(x,y,z);
        }
        if(w==3){
            scanf("%d%d",&x,&y);
            Add(x,y,0);Add(y,x,0);
        }
    }
    for(int i=1;i<=n;i++)Add(n+1,i,0);
    SPFA();
    if(!falg)printf("Yes\n");
    else printf("No\n");
    return 0;
}

 

推荐阅读