zoukankan      html  css  js  c++  java
  • hdu 3592 差分约束

    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")
    //end
    const 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")
    //end
    
    const 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;
    }

     

  • 相关阅读:
    ATOMac
    基于Python3 + appium的Ui自动化测试框架
    记 被难到的第一个算法题
    Requests发Post请求data里面嵌套字典
    Struts,Sping和Spirng MVC等框架分析
    雷军的留名,不是以程序员身份
    你有考虑过如果不做程序员,你会从事什么职业吗?或者你现在正在发展什么第二职业?
    java中的运算运算符 与或非(转)
    记录常用函数
    SQLServer记录常用函数(转)
  • 原文地址:https://www.cnblogs.com/lanjiangzhou/p/3005973.html
Copyright © 2011-2022 走看看