题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2582
解:这道题是老师给我们拿来当做考试的,结果考的时候,我在判断无向图联通块时,满脑子tarjan。。。完全忘了并查集。。。最后用了深搜,然而竟然92分??
这道题就是用并查集判断出分别的联通块,然后在一个联通块中,
if (u==e) 方案数为u(点的数量)
if (u==e-1) 方案数为 2
if (u<e) 无解。。。
然后乘起来就可以了
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #define INF 1000000007 using namespace std; int n,m,u,v,nume[200000],nump[200000],father[200000]; vector<int>edge[200000]; int findf(int x) { if (x==father[x]) return x; else { father[x]=findf(father[x]); return father[x]; } } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { scanf("%d%d",&u,&v); edge[u].push_back(v); } for (int i=1;i<=n;i++) father[i]=i,nump[i]=1; for (int i=1;i<=n;i++) for (int j=0;j<edge[i].size();j++) { int x=findf(i); int y=findf(edge[i][j]); if (x!=y) { father[y]=i; nump[x]+=nump[y];nump[y]=0;nume[x]+=nume[y];} nume[x]++; } long long ans=1; for (int i=1;i<=n;i++) int now=findf(i); for (int i=1;i<=n;i++) if (nump[i]) { if (nump[i]<nume[i]) { printf("0\n"); return 0; } else if (nump[i]>nume[i]) ans=(ans*nump[i])%INF; else ans=(ans*2)%INF; } printf("%lld\n",ans); return 0; }