hdu 3592 差分约束

来源:互联网 发布:adobe cc 2018mac破解 编辑:程序博客网 时间:2024/05/21 09:09

http://acm.hdu.edu.cn/showproblem.php?pid=3592

题意:有N个人按照1-N 的顺序排成一排,给你X个关于他们位置的关系,如:a, b ,c,则说明编号为a的人在标号为b 的人的前面(话说我实在没在原文中看到a必须在b前面,除非这句 Assume that there are N (2 <= N <= 1,000) people numbered 1..N who are standing in the same order as they are numbered. It is possible that two or more person line up at exactly the same location in the condition that those visit it in a group.应该是我英语不好的缘故),且两人最多相隔c距离,再给你Y给位置关系,给出的是a和b两个人至少相距c,问1号人和N号人最远相距多少。如果不存在这样的排序,则输出-1 ,如果1和N可以相距任意的距离,则输出-2, 否则输出最长的距离。

分析:在纸上写出式子就看出来了。

a[1]-a[3]<=8;                       >>>a[1]-a[3]<=8

a[2]-a[4]<=15;           转化为  >>>a[2]-a[4]<=15

a[2]-a[3]>=4                        >>>a[3]-a[2]<=-4

这样就可以建图了。

对于x

Createmap(a,b,w);

对于y

CreateMap(b,a,-w);

还有一个要注意的是:输出有3种情况。具体看代码。

View Code
//// I'm lanjiangzhou////C//#include <stdio.h>//#include <stdlib.h>// I'm lanjiangzhou//C#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <math.h>#include <time.h>//C++#include <iostream>#include <algorithm>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <cctype>#include <stack>#include <string>#include <list>#include <queue>#include <map>#include <vector>#include <deque>#include <set>using namespace std;//*************************OUTPUT*************************#ifdef WIN32#define INT64 "%I64d"#define UINT64 "%I64u"#else#define INT64 "%lld"#define UINT64 "%llu"#endif//**************************CONSTANT***********************#define INF 0x3f3f3f3f// aply for the memory of the stack//#pragma comment (linker, "/STACK:1024000000,1024000000")//endconst int maxn =1010;int head[maxn];int vis[maxn];int _count[maxn];//用来记录同一个点入队列的次数int n,cnt;struct point{    int v,next;//终点,指向下一条边    int w;//权值}edge[maxn*maxn];int dis[maxn];void CreateMap(int u,int v,int w){    edge[cnt].v=v;    edge[cnt].w=w;    edge[cnt].next=head[u];    head[u]=cnt++;}int spfa(){    memset(vis,0,sizeof(vis));    memset(_count,0,sizeof(_count));    for(int i=1;i<=n;i++){        dis[i]=INF;    }    dis[1]=0;    vis[1]=1;    _count[1]++;    queue<int> Q;    Q.push(1);    while(!Q.empty()){        int tmp=Q.front();        Q.pop();        vis[tmp]=0;        for(int i=head[tmp];i!=-1;i=edge[i].next){            if(dis[tmp]+edge[i].w<dis[edge[i].v]){                dis[edge[i].v]=dis[tmp]+edge[i].w;                if(!vis[edge[i].v]){                    Q.push(edge[i].v);                    vis[edge[i].v]=1;                    if((++_count[edge[i].v])>n)                        return -1;//存在负权回路                }            }        }    }    if(dis[n]==INF) return -2;    return dis[n];    //return 1;}int main(){    //int temp;    //double l,u;    int t;    int x,y;    int u,v,w;    scanf("%d",&t);    while(t--){        memset(head,-1,sizeof(head));        scanf("%d%d%d",&n,&x,&y);        cnt=1;        //int temp;        for(int i=1;i<=x;i++){            scanf("%d%d%d",&u,&v,&w);            CreateMap(u,v,w);           // for(int j=1;j<=m;j++){                //scanf("%d",&temp);               // CreateMap(i,j+n,-log(l*1.0/temp));               // CreateMap(j+n,i,log(u*1.0/temp));           // }        }        for(int i=1;i<=y;i++){            scanf("%d%d%d",&u,&v,&w);            CreateMap(v,u,-w);        }        printf("%d\n",spfa());        //int flag=spfa();        //if(flag) printf("%d\n",dis[n]);        //else  if(dis[n]==INF) printf("-2\n");        //else  if(!flag)   printf("-1\n");    }    return 0;}

还有一个小点,我用bellman_ford()一直有问题。再试试吧。加油小菜鸟州。

下面是bellman_ford算法做的还没做出来。

View Code
// I'm lanjiangzhou//C#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <math.h>#include <time.h>//C++#include <iostream>#include <algorithm>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <cctype>#include <stack>#include <string>#include <list>#include <queue>#include <map>#include <vector>#include <deque>#include <set>using namespace std;//*************************OUTPUT*************************#ifdef WIN32#define INT64 "%I64d"#define UINT64 "%I64u"#else#define INT64 "%lld"#define UINT64 "%llu"#endif//**************************CONSTANT***********************#define INF 0x3f3f3f3f //aply for the memory of the stack//#pragma comment (linker, "/STACK:1024000000,1024000000")//endconst int nmax = 1000+10;const int emax = 23000+100;int n;//一共有几个大营int m;//已知从第i个大营到第j个大营至少有几个士兵,这些信息有m条int c[nmax];//第i个大营最多有c[i]个士兵int d[nmax];//d[0]=0;  d[1]=c[1];  d[2]=c[1]+c[2]....即d[i]为前i个大营容量总和int ei;//边的序号int dis[nmax];//从源点到个顶点最短路径长度(注意:源点为sn而不是s0)struct eg{    int u,v,w;//边:起点,终点,权值}edges[emax];void init(){    ei=0;    //除源点sn外,其他顶点的最短距离初始为inf   // 则bellman_ford算法的第一重要循环n-1次    for(int i=1;i<=n;i++) {        dis[i]=INF;    }    dis[1]=0;    dis[n]=0; //一下bellman_ford算法是以sn为源点的,所以dis[n]=0;}bool bellman_ford(){    //init();    //bellman_ford()//算法的第一重循环要执行n-1次,n是网络中顶点的个数    //本题中顶点个数n+1;    for(int i=1;i<=n;i++){     //   假设第k条边的起点是u,终点是v,以下循环考虑第k条边是否会使得源点v0到v的最短距离缩短,      //  即判断dis[edges[k].u]+edges[k].w<dis[edges[k].v]是否成立        for(int k=1;k<=ei;k++){            int t=dis[edges[k].u]+edges[k].w;            if(dis[edges[k].u]!=INF&&t<dis[edges[k].v]){                dis[edges[k].v]=t;               // printf("t=%d\n",t);            }        }    }    //以下是检查,若还有更新则说明存在无限循环的负值回路    for(int k=1;k<=ei;k++){        if(dis[edges[k].u]!=INF&&dis[edges[k].u]+edges[k].w<dis[edges[k].v]){            return -1;        }    }    if(dis[n]==INF) return -2;    return dis[n];    //return true;}int main(){    int t;    scanf("%d",&t);    while(t--){        //init();        int x,y;        scanf("%d%d%d",&n,&x,&y);        //init();        int u,v,w;        for(int i=1;i<=x;i++){            scanf("%d%d%d",&u,&v,&w);            edges[ei].u=u;            edges[ei].v=v;            edges[ei].w=w;            ei++;        }        for(int j=1;j<=y;j++){            scanf("%d%d%d",&u,&v,&w);            edges[ei].u=v;            edges[ei].v=u;            edges[ei].w=-w;//构造边<v,u-1>  权值为-w;            ei++;        }        init();        printf("%d\n",bellman_ford());       // int ans=bellman_ford();        //if(ans) printf("-1\n");        //else printf("%d\n",dis[n]);    }    return 0;}