[SCOI2011]糖果

题目大意:
  有n个正整数,k个约束条件。条件分为5种:
    1.a和b相等;
    2.a小于b;
    3.a不小于b;
    4.a大于b;
    5.a不大于b。
  问条件是否矛盾,如果不矛盾,求它们最小和。

思路:
  差分约束。
  把数当作点,约束关系当作边,跑SPFA,如果有环则说明矛盾。

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<vector>
 5 typedef long long int64;
 6 inline int getint() {
 7     register char ch;
 8     while(!isdigit(ch=getchar()));
 9     register int x=ch^'0';
10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
11     return x;
12 }
13 const int N=100001;
14 struct Edge {
15     int to,w;
16 };
17 std::vector<Edge> e[N];
18 inline void add_edge(const int &u,const int &v,const int &w) {
19     e[u].push_back((Edge){v,w});
20 }
21 bool inq[N];
22 std::queue<int> q;
23 int dis[N],cnt[N],n;
24 bool spfa() {
25     q.push(0);
26     inq[0]=true;
27     while(!q.empty()) {
28         const int x=q.front();
29         q.pop();
30         inq[x]=false;
31         if(++cnt[x]>=n) return false;
32         for(register unsigned i=0;i<e[x].size();i++) {
33             const int &y=e[x][i].to,&w=e[x][i].w;
34             if(dis[x]+w>dis[y]) {
35                 dis[y]=dis[x]+w;
36                 if(!inq[y]) {
37                     q.push(y);
38                     inq[y]=true;
39                 }
40             }
41         }
42     }
43     return true;
44 }
45 int main() {
46     n=getint();
47     for(register int k=getint();k;k--) {
48         int t=getint(),a=getint(),b=getint();
49         if(t==1) {
50             add_edge(a,b,0);
51             add_edge(b,a,0);
52         }
53         if(t==2) {
54             if(a==b) {
55                 puts("-1");
56                 return 0;
57             }
58             add_edge(a,b,1);
59         }
60         if(t==3) add_edge(b,a,0);
61         if(t==4) {
62             if(a==b) {
63                 puts("-1");
64                 return 0;
65             }
66             add_edge(b,a,1);
67         }
68         if(t==5) add_edge(a,b,0);
69     }
70     for(register int i=1;i<=n;i++) {
71         add_edge(0,i,1);
72     }
73     if(!spfa()) {
74         puts("-1");
75         return 0;
76     }
77     int64 ans=0;
78     for(register int i=1;i<=n;i++) ans+=dis[i];
79     printf("%lld\n",ans);
80     return 0;
81 }

 

posted @ 2017-12-28 16:02  skylee03  阅读(86)  评论(0编辑  收藏  举报