POJ 3169 Layout

差分约束系统。

由题意直接可以得到一系列不等式,直接可以建图跑最短路。

如果存在负环,那么输出-1,如果1到n的最短路距离无穷大,那么输出-2,其余输出1到n的最短路距离。

关于查分约束系统可以看这篇博客http://www.cnblogs.com/void/archive/2011/08/26/2153928.html

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const long long INF=9223372036854775807;
const int maxn=1000+10;
int n,ml,md;
struct Edge
{
    int u,v;
    long long cost;
}e[20*maxn];
vector<int>G[maxn];
bool flag[maxn];
long long dis[maxn];
int tot[maxn];
long long ans;

void init()
{
    for(int i=1;i<=n;i++) G[i].clear();
    memset(flag,0,sizeof flag);
    memset(tot,0,sizeof tot);
    for(int i=1;i<=n;i++) dis[i]=INF;
    ans=-3;
}

void read()
{
    for(int i=1;i<=ml;i++)
    {
        int a,b; long long d; scanf("%d%d%lld",&a,&b,&d);
        e[i].u=a; e[i].v=b; e[i].cost=d;
        G[a].push_back(i);
    }

    for(int i=1;i<=md;i++)
    {
        int a,b; long long d; scanf("%d%d%lld",&a,&b,&d);
        e[i+ml].u=b; e[i+ml].v=a; e[i+ml].cost=-d;
        G[b].push_back(i+ml);
    }
}

void SPFA()
{
    queue<int>Q; flag[1]=1; dis[1]=0; Q.push(1);
    while(!Q.empty())
    {
        int head=Q.front(); Q.pop(); flag[head]=0;
        tot[head]++; if(tot[head]>n) {ans=-1; break;}
        for(int i=0;i<G[head].size();i++)
        {
            int id=G[head][i];
            int to=e[id].v;
            long long c=e[id].cost;

            if(dis[head]+c<dis[to])
            {
                dis[to]=dis[head]+c;
                if(!flag[to]) { flag[to]=1; Q.push(to); }
            }
        }
    }

    if(ans!=-1)
    {
        if(dis[n]==INF) ans=-2;
        else ans=dis[n];
    } 
    printf("%lld\n",ans);
}

int main()
{
    while(~scanf("%d%d%d",&n,&ml,&md))
    {
        init(); 
        read(); 
        SPFA();
    }
    return 0;
}

 

posted @ 2016-03-14 20:33  Fighting_Heart  阅读(152)  评论(0编辑  收藏  举报