Central Europe Regional Contest 2012 Problem J: Conservation

题目不难,感觉像是一个拓扑排序,要用双端队列来维护;

要注意细节,不然WA到死  = =!

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #define maxn 100005
 5 using namespace std;
 6 
 7 int q[2*maxn],count[2][maxn],tail,head,n,m,in[maxn];
 8 vector<int>ve[maxn];
 9 
10 int solve(int lab)
11 {
12     head=tail=n;
13     int cnt=0,cc=0,f=lab;
14     for(int i=1;i<=n;i++)
15         if(count[2-lab][i]==0&&in[i]==lab){q[tail++]=i;cnt++;}
16     if(cnt==0)return -1;
17     for(int i=1;i<=n;i++)
18         if(count[2-lab][i]==0&&in[i]!=lab){q[tail++]=i;}
19     while(head<tail)
20     {
21         int v=q[head++];
22         if(in[v]!=f){f=in[v];cc++;}
23         int l=ve[v].size();
24         for(int i=0;i<l;i++)
25         {
26             count[2-lab][ve[v][i]]--;
27             if(count[2-lab][ve[v][i]]==0)
28             {
29                 if(in[v]==in[ve[v][i]])
30                     q[--head]=ve[v][i];
31                 else q[tail++]=ve[v][i];
32             }
33         }
34     }
35     return cc;
36 }
37 
38 int main()
39 {
40     int t,x,y;
41     scanf("%d",&t);
42     while(t--)
43     {
44         scanf("%d%d",&n,&m);
45         for(int i=1;i<=n;i++)ve[i].clear();
46         memset(count,0,sizeof count);
47         for(int i=1;i<=n;i++)scanf("%d",&in[i]);
48         for(int i=1;i<=m;i++)
49         {
50             scanf("%d%d",&x,&y);
51             ve[x].push_back(y);
52             count[0][y]++;
53             count[1][y]++;
54         }
55         x=solve(1);
56         y=solve(2);
57         if(x<0||y<0)printf("%d\n",max(x,y));
58         else printf("%d\n",min(x,y));
59     }
60     return 0;
61 }
View Code

 

posted @ 2013-10-03 18:01  Yours1103  阅读(248)  评论(0编辑  收藏  举报