题解—— 洛谷 p1993 小K的农场(差分约束&负环判断)

看到题就可以想到差分约束

判断负环要用dfs,bfs-spfa会TLE 4个点

bfs-spfa

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = 30101;
const int MAXM = 100101;
int cnt=0,u[MAXM],v[MAXM],w[MAXM],first[MAXN],next[MAXM];
bool vis[MAXN];
int inq[MAXN],dis[MAXN],f[MAXN];
int n,m;
void addedge(int ux,int vx,int wx){
    ++cnt;
    u[cnt]=ux;
    v[cnt]=vx;
    w[cnt]=wx;
    next[cnt]=first[ux];
    first[ux]=cnt;
}
bool spfa(int s,int t){
    queue<int> q;
    for(int i=0;i<=n+1;i++){
        dis[i]=0x3f3f3f3f;
        }
    q.push(s);
    dis[s]=0;
    inq[s]=1;
    vis[s]=1;
    f[s]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        f[u]=1;
        for(int i=first[u];i;i=next[i]){
            if(w[i]+dis[u]<dis[v[i]]){
                dis[v[i]]=w[i]+dis[u];
                if(!vis[v[i]]){
                    vis[v[i]]=1;
                    inq[v[i]]++;
                    q.push(v[i]);
                    if(inq[v[i]]>n)
                        return false;
                }
            }
        }
    }
    return true;
}
int main(){
    cin>>n>>m;
    int a,b,c,mode;
    for(int i=1;i<=m;i++){
        cin>>mode;
        if(mode==1){
        cin>>a>>b>>c;
        addedge(a,b,-c);
        }
        else if(mode==2){
        cin>>a>>b>>c;
        addedge(b,a,c);
        }
        else{
            cin>>a>>b;
            addedge(a,b,0);
            addedge(b,a,0);
        }
    }
    for(int i=1;i<=n;i++)
        if(!f[i])
            if(!spfa(i,0)){
                printf("No\n");
                return 0;
            }
    printf("Yes\n");
    return 0;
}

dfs-spfa

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = 30101;
const int MAXM = 100101;
int cnt=0,u[MAXM],v[MAXM],w[MAXM],first[MAXN],next[MAXM];
int vis[MAXN];
int inq[MAXN],dis[MAXN],f[MAXN];
int n,m;
void addedge(int ux,int vx,int wx){
    ++cnt;
    u[cnt]=ux;
    v[cnt]=vx;
    w[cnt]=wx;
    next[cnt]=first[ux];
    first[ux]=cnt;
}
bool flag=false;
void spfa(int ux){
    vis[ux]=1;
    for(int i=first[ux];i;i=next[i]){
        if(dis[ux]+w[i]<dis[v[i]]){
            if(vis[v[i]]){
                flag=true;
                return;    
            }
            dis[v[i]]=dis[ux]+w[i];
            spfa(v[i]);
        }
    }
    vis[ux]=0;
    return;
}
int main(){
    cin>>n>>m;
    int a,b,c,mode;
    for(int i=1;i<=m;i++){
        cin>>mode;
        if(mode==1){
        cin>>a>>b>>c;
        addedge(a,b,-c);
        }
        else if(mode==2){
        cin>>a>>b>>c;
        addedge(b,a,c);
        }
        else{
            cin>>a>>b;
            addedge(a,b,0);
            addedge(b,a,0);
        }
    }
    for(int i=1;i<=n;i++){
        dis[i]=0;
        spfa(i);
        if(flag){
            printf("No\n");
            return 0;
        }
    }
    printf("Yes\n");
    return 0;
}

 

posted @ 2018-08-06 07:53  dreagonm  阅读(138)  评论(0编辑  收藏  举报