首页 > 代码库 > 【bzoj2330】: [SCOI2011]糖果 图论-差分约束-SPFA

【bzoj2330】: [SCOI2011]糖果 图论-差分约束-SPFA

【bzoj2330】: [SCOI2011]糖果

恩。。就是裸的差分约束。。

x=1 -> (A,B,0) (B,A,0)

x=2 -> (A,B,1)  [这个情况加个A==B无解的要特判]

x=3 -> (B,A,0)  [恩这个是不少于一开始zz建反了]

x=4 -> (B,A,1) 

x=5 -> (A,B,0) 

然后源点到所有点建1的边[恩据说有条链所以要反着连]跑最长路就好了

技术分享
 1 /* http://www.cnblogs.com/karl07/ */
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <queue>
 8 using namespace std;
 9 
10 const int N=100005; 
11 struct edge{
12     int next,to,v;
13 }e[N*4];
14 
15 int n,k,ade=0;
16 int first[N],dis[N],vis[N],tim[N];
17 queue <int> q;
18 
19 void addedge(int x,int y,int v){
20     e[++ade].to=y;
21     e[ade].next=first[x];
22     e[ade].v=v;
23     first[x]=ade;
24 }
25 
26 #define s e[x].to
27 #define v e[x].v
28 long long spfa(){
29     q.push(n+1),vis[n+1]=1;
30     while (!q.empty()){
31         int p=q.front();
32         q.pop(),vis[p]=0;
33         for (int x=first[p];x;x=e[x].next){
34             if (dis[s]<dis[p]+v){
35                 dis[s]=dis[p]+v;
36                 if (!vis[s]) vis[s]=1,q.push(s);
37                 tim[s]++;
38             }
39             if (tim[s]>n+1) return -1;
40         }
41     }
42     long long ans=0;
43     for (int i=1;i<=n;i++) ans+=dis[i];
44     return ans;
45 }
46 #undef v
47 #undef s
48 
49 int main(){
50     scanf("%d%d",&n,&k);
51     for (int i=1,a,b,x;i<=k;i++){
52         scanf("%d%d%d",&x,&a,&b);
53         if (x==1) addedge(a,b,0),addedge(b,a,0);
54         if (x==2) if (a==b) {puts("-1"); return 0;} else addedge(a,b,1);
55         if (x==3) addedge(b,a,0);
56         if (x==4) if (a==b) {puts("-1"); return 0;} else addedge(b,a,1);
57         if (x==5) addedge(a,b,0);
58     }
59     for (int i=n;i>=1;i--) addedge(n+1,i,1);
60     printf("%lld\n",spfa());
61     return 0;
62 }
63  
View Code

蒟蒻退役前两天又开始更博客了。。期中考试和地理二模两个星期啥也没干。。然后明天就SHOI了。。

【bzoj2330】: [SCOI2011]糖果 图论-差分约束-SPFA