您的位置:首页 > 运维架构

Central Europe Regional Contest 2012 Problem J: Conservation

2013-10-03 18:01 387 查看
题目不难,感觉像是一个拓扑排序,要用双端队列来维护;

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

#include<cstdio>
#include<cstring>
#include<vector>
#define maxn 100005
using namespace std;

int q[2*maxn],count[2][maxn],tail,head,n,m,in[maxn];
vector<int>ve[maxn];

int solve(int lab)
{
head=tail=n;
int cnt=0,cc=0,f=lab;
for(int i=1;i<=n;i++)
if(count[2-lab][i]==0&&in[i]==lab){q[tail++]=i;cnt++;}
if(cnt==0)return -1;
for(int i=1;i<=n;i++)
if(count[2-lab][i]==0&&in[i]!=lab){q[tail++]=i;}
while(head<tail)
{
int v=q[head++];
if(in[v]!=f){f=in[v];cc++;}
int l=ve[v].size();
for(int i=0;i<l;i++)
{
count[2-lab][ve[v][i]]--;
if(count[2-lab][ve[v][i]]==0)
{
if(in[v]==in[ve[v][i]])
q[--head]=ve[v][i];
else q[tail++]=ve[v][i];
}
}
}
return cc;
}

int main()
{
int t,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)ve[i].clear();
memset(count,0,sizeof count);
for(int i=1;i<=n;i++)scanf("%d",&in[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
ve[x].push_back(y);
count[0][y]++;
count[1][y]++;
}
x=solve(1);
y=solve(2);
if(x<0||y<0)printf("%d\n",max(x,y));
else printf("%d\n",min(x,y));
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: