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 }

 

你可能感兴趣的:(sc)