• bzoj2330(差分约束)


    题解:这道题是练差分约束的一道好题目吧,我具体在代码中注释,这样更加好理解,

    为什么求最长路呢?因为这样保证了满足条件,如果存在正权环,就表示无解,就是

    正权环之间不断要更多的糖果才行。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<queue>
     7 using namespace std;
     8 
     9 typedef long long ll;
    10 const int N=100007;
    11 
    12 int s,dis[N],mark[N],n,m;
    13 int cnt=0,head[N],next[N*3],rea[N*3],val[N*3];
    14 bool vis[N];
    15 
    16 void add(int u,int v,int fee)
    17 {
    18     cnt++;
    19     next[cnt]=head[u];
    20     head[u]=cnt;
    21     rea[cnt]=v;
    22     val[cnt]=fee;
    23 }
    24 bool spfa()
    25 {
    26     queue<int>q;
    27     q.push(0);
    28     vis[dis[0]=0]=1;
    29     while(!q.empty())
    30     {
    31         int u=q.front();q.pop();
    32         for(int i=head[u];i!=-1;i=next[i])
    33         {
    34             int v=rea[i],fee=val[i];
    35             if(dis[u]+fee>dis[v])
    36             {
    37                 dis[v]=dis[u]+fee;
    38                 if(++mark[v]>=n) return 0;//表示无法满足 
    39                 if(!vis[v])
    40                 {
    41                     vis[v]=1;
    42                     q.push(v);
    43                 }
    44             }
    45         }
    46         vis[u]=0;
    47     }
    48     return 1;
    49 }
    50 int main()
    51 {
    52     memset(head,-1,sizeof(head));
    53     scanf("%d%d",&n,&m);
    54     for (int i=1;i<=m;i++)
    55     {
    56         int xh,u,v;
    57         scanf("%d%d%d",&xh,&u,&v);
    58         switch (xh)
    59         {
    60             case 1:if(u!=v) add(u,v,0),add(v,u,0);
    61                 break;
    62             case 2:if(u==v)
    63                 {
    64                     printf("-1");
    65                     return 0;
    66                 }
    67                 add(u,v,1);break;                    
    68             case 3:if(u!=v) add(v,u,0);break;//表示可以到达 
    69             case 4:if(u==v)
    70                 {
    71                     printf("-1");
    72                     return 0;
    73                 }
    74                 add(v,u,1);break;//因为最少,所以只要多一格糖果就可以了。 
    75             case 5:if(u!=v) add(u,v,0);break;
    76         }
    77     }
    78     for(int i=n;i;i--)
    79         add(0,i,1);//初始,开辟超源点。 
    80     if(!spfa()) printf("-1");
    81     else
    82     {
    83         ll ans=0;
    84         for(int i=1;i<=n;i++) 
    85             ans+=dis[i];
    86         printf("%lld
    ",ans);
    87     }
    88 }
  • 相关阅读:
    【数论】X problem
    【数论】约瑟夫问题
    【组合数学】购票问题
    【组合数学】计数原理
    spring batch批处理框架学习
    eclipse自动添加javadoc注释
    eclipse手动安装alibaba代码规范插件
    现代支付系统的资金流向
    利用网易有道在谷歌浏览器进行网页滑词翻译
    spring配置遇到的问题
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7429671.html
Copyright © 2020-2023  润新知