标签:方法 简单 编写 scanf else 学习 end for har
{1},{2,4,6},{3,5}
一开始的想法和ABC野兽那道题一样,可以维护每个点和祖先的关系。而且似乎更简单。于是有了下面的程序
#include<iostream> #include<cstdio> using namespace std; int fa[1010],deep[1010],ans[1010][2],n,m; int getf(int k){ if(fa[k]!=k){ int t=fa[k]; fa[k]=getf(fa[k]); deep[k]=deep[k]+deep[t]; deep[k]=deep[k]%2; } return fa[k]; } int main(){ cin>>n>>m; for(int i=1;i<=n;++i){ fa[i]=i; deep[i]=0; } for(int i=1;i<=m;++i){ char c[2]; int x,y; scanf("%s%d%d",&c,&x,&y); if((c[0]==‘1‘)&&(getf(x)!=getf(y))){ int fx=getf(x); int fy=getf(y); deep[fx]=(deep[y]-deep[x]+3)%2; fa[fx]=fy; } if((c[0]==‘0‘)&&(getf(x)!=getf(y))){ int fx=getf(x); int fy=getf(y); deep[fx]=(deep[y]-deep[x]+2)%2; fa[fx]=fy; } } for(int i=1;i<=n;++i){ fa[i]=getf(i); //cout<<fa[i]<<" "<<deep[i]<<endl; ans[fa[i]][deep[i]]++; } int add=0; for(int i=1;i<=n;++i) for(int j=0;j<=1;++j)if(ans[i][j]>0){ add++; } cout<<add; return 0; }
然后、、、、、、就爆0了。
哪里出了问题?忽然发现题设中并没有:我的敌人的朋友是我的敌人。MDZZ!这不符合逻辑啊,虽然NOI从来不讲逻辑。
重新出发,想到分点的方法。通过朋友相关联的,fa[x]=y;通过敌人相关联的,fa[x]=y+n,fa[x+n]=y。该题完美解决。楼下程序:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int n,m,ans,a[1010]; int fa[2020]; int Find(int x) { if(!fa[x]||fa[x]==x) return fa[x]=x; return fa[x]=Find(fa[x]); } void Union(int x,int y) { x=Find(x);y=Find(y); if(x==y) return ; fa[x]=y; } int main(){ int i,x,y; char p[10]; cin>>n>>m; for(i=1;i<=m;i++) { scanf("%s%d%d",p,&x,&y); if(p[0]==‘F‘) Union(x,y); else Union(x,y+n),Union(x+n,y); } for(i=1;i<=n;i++) a[i]=Find(i); sort(a+1,a+n+1); for(i=1;i<=n;i++) if(i==1||a[i]!=a[i-1]) ++ans; cout<<ans<<endl; return 0; }
To be continue......
标签:方法 简单 编写 scanf else 学习 end for har
原文地址:http://www.cnblogs.com/cxl681237/p/6164073.html