bzoj 1731/hdu 3592(差分约束)

来源:互联网 发布:淘宝官方 编辑:程序博客网 时间:2024/05/29 03:29

传送门
题解:
定向之后(小编号连大编号),”≥”连(b,a,-c),”≤”连(a,b,c),跑最短路

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int MAXN=1002,MAXM=20004,INF=0x3f3f3f3f;int kase;int n,X,Y,a,b,c;int head[MAXN],edge;struct EDGE {    int v,nxt,w;}e[MAXM];int dis[MAXN],in[MAXN];bool vis[MAXN];void adde(int u,int v,int w) {    e[++edge].nxt=head[u],e[edge].v=v,e[edge].w=w,head[u]=edge;}inline int spfa(int source,int sink) {    queue<int> q;    memset(in,0,sizeof(in));    memset(vis,false,sizeof(vis));    memset(dis,INF,sizeof(dis));    q.push(1),vis[1]=true,dis[1]=0,in[1]=1;    while (!q.empty()) {        int p=q.front();        q.pop();        vis[p]=false;        for (int i=head[p];~i;i=e[i].nxt) {            int v=e[i].v;            if (dis[v]>dis[p]+e[i].w) {                dis[v]=dis[p]+e[i].w;                if (!vis[v]) {                    vis[v]=true;                    q.push(v);                    if (++in[v]>n) return -1;                }            }        }    }    if (dis[sink]==INF) return -2;    return dis[sink];}int main() {//  freopen("hdu 3592.in","r",stdin);    scanf("%d",&kase);    while (kase--) {        edge=0;        memset(head,-1,sizeof(head));        scanf("%d%d%d",&n,&X,&Y);        for (int i=0;i<X;++i) {            scanf("%d%d%d",&a,&b,&c);            if (a>b) a^=b^=a^=b;            adde(a,b,c);        }        for (int i=0;i<Y;++i) {            scanf("%d%d%d",&a,&b,&c);            if (a>b) a^=b^=a^=b;            adde(b,a,-c);        }        printf("%d\n",spfa(1,n));    }    return 0;}