bzoj3436

题解:

查分约数系统

1情况:x->y 建立条-z

2情况:y->x 建一条z

3情况:x->y建一条0

然后0对于每一个点见一个0

跑一下最短路,看是否又负环

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,pd,x,b[N*10],dis[N],f[N],cost[N],num,sl[N],y,z,fi[N],ne[N],zz[N];
void jb(int x,int y,int z)
{
    ne[++num]=fi[x];
    fi[x]=num;
    zz[num]=y;
    sl[num]=z;
}
int main()
{
    scanf("%d%d",&n,&m);
    while (m--)
     {
         scanf("%d",&pd);
         if (pd==1)
          {
              scanf("%d%d%d",&x,&y,&z);
              jb(x,y,-z);
          }
         if (pd==2)
         {
             scanf("%d%d%d",&x,&y,&z);
             jb(y,x,z);
         }
        if (pd==3)
         {
             scanf("%d%d",&x,&y);
             jb(x,y,0);
         } 
     }
    int l=0,r=1;
    f[0]=cost[0]=1;
    memset(dis,0x3f,sizeof dis);
    dis[0]=0;
    for (int i=1;i<=n;i++)jb(0,i,0);
    while (l!=r)
     {
         int num=b[l++];
         l%=(N*10);
         f[num]=0;
         for (int i=fi[num];i;i=ne[i])
          {
              int t=zz[i];
              if (dis[t]>dis[num]+sl[i])
               {
                   dis[t]=dis[num]+sl[i];
                   if (!f[t])
                    {
                        f[t]=1;
                        b[r++]=t;
                        r%=(N*10);
                        cost[t]++;
                        if (cost[t]>=n)
                         {
                             puts("No");
                             return 0;
                         } 
                    }
               }
          }
     } 
    puts("Yes"); 
    return 0;
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8228385.html