• poj 2679 Adventurous Driving(SPFA 负环)


    /*
    - -
    这题做了一天.....粗心害死人啊 题目描述恶心 数据更恶心... 
    先处理一下能走的边 能走的点(到这建边从终点跑一下.)
    然后就是SPFA了 注意负环的判断 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define maxn 1110
    #define maxm 10010
    #define inf 999999999
    using namespace std;
    int n,m,num,num2,head[maxn],s,t,vis[maxm];
    int ans[maxm],size,f[maxn],falg,Dis[maxn],Ti[maxn];//ans存能走的边 并不是一个点对应一条边 要用maxm! 
    int sum[maxn],can[maxn],head2[maxn];
    struct node
    {
        int u,v,ti,si,pre;
    }e[maxm],e2[maxm];
    queue<int>q;
    int init()
    {
        int x=0;char s;bool f=0;s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        if(f)return -x;else return x;
    }
    void Add(int from,int to,int cost,int len)
    {
        num++;
        e[num].u=from;
        e[num].v=to;
        e[num].si=len;
        e[num].ti=cost;
        e[num].pre=head[from];
        head[from]=num;
    }
    void Add2(int from,int to,int cost,int len)
    {
        num2++;
        e2[num2].u=from;
        e2[num2].v=to;
        e2[num2].si=len;
        e2[num2].ti=cost;
        e2[num2].pre=head2[from];
        head2[from]=num2;
    }
    void Edge_can()//能走的边 
    {
        for(int i=0;i<=n;i++)
          {
            int minn=inf,k;
            for(int j=head[i];j;j=e[j].pre)
              if(e[j].ti<minn)
                minn=e[j].ti;
            for(int j=head[i];j;j=e[j].pre)
              if(e[j].ti==minn)
                ans[++size]=j;
          }
        for(int i=1;i<=size;i++)vis[ans[i]]=1;
    }
    void Bfs(int x)
    {
        queue<int>qi;
        qi.push(x);
        can[x]=1;
        while(!qi.empty())
          {
              int k=qi.front();
              qi.pop();
              for(int i=head2[k];i;i=e2[i].pre)
                if(can[e2[i].v]==0)
                  {
                    qi.push(e2[i].v);
                    can[e2[i].v]=1;
                }
          }
    }
    void Point_can()//到这建边搜能走的点 
    {
        for(int i=1;i<=num;i++)
          if(vis[i])
            Add2(e[i].v,e[i].u,e[i].ti,e[i].si);
        Bfs(t);
    }
    void SPFA(int st)
    {
        q.push(st);
        f[st]=1;
        sum[st]++;
        Dis[st]=0;
        Ti[st]=0;
        while(!q.empty())
          {
              int now=q.front();
              q.pop();
              f[now]=0;
              if(sum[now]>n+5)//负环死循环 
                {
                    falg=1;
                    break;
              }
              for(int i=head[now];i;i=e[i].pre)
                if((Ti[now]+e[i].ti<Ti[e[i].v]||(Ti[now]+e[i].ti==Ti[e[i].v]&&
                Dis[now]+e[i].si<Dis[e[i].v]))&&vis[i]&&can[e[i].v])//没有 f[e[i].v]==0 !!!
                  {
                    Ti[e[i].v]=Ti[now]+e[i].ti;
                    Dis[e[i].v]=Dis[now]+e[i].si;
                    if(f[e[i].v]==0)
                      {
                        q.push(e[i].v);
                      f[e[i].v]=1;
                      sum[e[i].v]=sum[now]+1;    
                    }
                }
          }
    }
    int main()
    {
        while(~scanf("%d%d%d%d",&n,&m,&s,&t))
          {
              n--;
              memset(head,0,sizeof(head));memset(ans,0,sizeof(ans));//多组数据....注意初始化 
              memset(vis,0,sizeof(vis));memset(can,0,sizeof(can));
              memset(f,0,sizeof(f));memset(sum,0,sizeof(sum));
              memset(Dis,127/3,sizeof(Dis));memset(Ti,127/3,sizeof(Ti));
              memset(head2,0,sizeof(head2));
              size=0;num=0;falg=0;num2=0;
              int ui,vi,dis,cost1,cost2;
              for(int i=1;i<=m;i++)
                {
                    ui=init();
                    vi=init();
                    cost1=init();
                    dis=init();
                    cost2=init();
                    Add(ui,vi,cost1,dis);
                    Add(vi,ui,cost2,dis);
              }
            Edge_can();
            Point_can();
            if(can[s]==0)//跑不到终点  
              {
                  printf("VOID
    ");
                  continue;
              }
            SPFA(s);
            if(falg==1)printf("UNBOUND
    ");//能跑到 并且有负环  
            if(falg==0)printf("%d %d
    ",Ti[t],Dis[t]);
          }
        return 0;
    }
  • 相关阅读:
    sqlzoo练习答案--SUM and COUNT
    响应式的嵌入内容和图片
    缓存server设计与实现(五)
    编译器DIY——读文件
    [Leetcode]-Pascal&#39;s Triangle
    zoj 1562 反素数 附上个人对反素数性质的证明
    [POJ 1236][IOI 1996]Network of Schools
    POJ 3691 DNA repair [AC自动机 DP]
    POJ 1625 Censored! [AC自动机 高精度]
    51Nod 1225 余数之和 [整除分块]
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5485758.html
Copyright © 2020-2023  润新知