SCOI 2011糖果

差分约束系统,题意非常明显,比较简单。

1、题目中有冲突的数据需要特判。

2、注意读题:每个小朋友都必须分到糖果,所以最后的答案要加n

3、注意差分约束系统有两种形式:最长路和最短路(对应≥和≤)

其中最长路解出来的结果是最小值,最短路解出来的结果是最大值。(都是接近常数);

要根据题意选取适当的形式;

View Code
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <queue>
 4 #include <cstring>
 5 #define S n+1
 6 #define N 100000+10
 7 #define M 1000000+10
 8 #define INF 9999999
 9 using namespace std;
10 //Global
11 int head[N],next[M],e[M],w[M],countside=1;
12 int n,k;
13 //Function
14 void buildside(int a,int b,int c){
15     e[countside]=b;
16     w[countside]=c;
17     next[countside]=head[a];
18     head[a]=countside;
19     countside++;
20 }
21 int spfa(int s){
22     int i,relax[N];
23     bool inq[N];
24     int dis[N];
25     memset(inq,false,sizeof(inq));
26     memset(relax,0,sizeof(relax));
27     for (i=1;i<=n+10;i++)
28         dis[i]=-INF;
29     dis[s]=0;
30     queue<int> q;
31     q.push(s);
32     inq[s]=true;
33     while (!q.empty()){//printf("outed");
34         int now=q.front();
35         q.pop();
36         inq[now]=false;
37         for (i=head[now];i>0;i=next[i]){
38             if (dis[e[i]]<dis[now]+w[i]){
39                 dis[e[i]]=dis[now]+w[i];
40                 relax[e[i]]++;
41                 if (relax[e[i]]>n+3)    return -1;
42                 if (!inq[e[i]]){
43                     q.push(e[i]);
44                     inq[e[i]]=true;
45                 }
46             }
47         }
48     }
49     int ans=0;
50     for (i=1;i<=n;i++)
51         ans+=dis[i];
52     return ans;
53 }
54 int main()
55 {
56     int i,x,a,b;
57     scanf("%d%d",&n,&k);
58     for (i=1;i<=k;i++)
59     {
60         scanf("%d%d%d",&x,&a,&b);
61         if (x==3) buildside(b,a,0);//xb-xa<=0
62         if (x==5) buildside(a,b,0);//xa-xb<=0
63         if (x==2){
64             if (a==b)    {printf("-1\n");return 0;}
65             buildside(a,b,1);//xa-xb<=-1
66         }
67         if (x==4){
68             if (a==b)    {printf("-1\n");return 0;}
69             buildside(b,a,1);//xb-xa<=-1
70         }
71         if (x==1){
72             buildside(a,b,0);
73             buildside(b,a,0);
74             //xa-xb<=0&&xb-xa<=0
75         }
76     }
77     for (i=1;i<=n;i++)
78         buildside(S,i,0);
79     int ans=spfa(S);
80     if (ans==-1)    printf("-1\n");
81     else printf("%d\n",ans+n);
82     return 0;
83 }

 

posted @ 2013-02-02 11:05  wsc500  阅读(514)  评论(0编辑  收藏  举报