[USACO12JAN]牛联盟Bovine Alliance
传送门:https://www.luogu.org/problemnew/show/P3043
其实这道题十分简单。。看到大佬们在用tarjan缩点,并查集合并。。。。
蒟蒻渣渣禹都不会。
渣渣禹发现,给出的图经过处理之后会出现:
环。
不是环。
不是环的情况我们有n中匹配方式(n为其点的个数)
是环的情况我们只有两种匹配方式,顺时针匹配和逆时针匹配。
所以我们dfs处理出图中有多少个环,和不是环的个数。
ans 初始为1.
遇到环ans乘二,否则ans乘n(n为这个不是环的点的个数)。
结束咯w。
#define B cout << "BreakPoint" << endl; #define O(x) cout << #x << " " << x << endl; #define O_(x) cout << #x << " " << x << " "; #define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl; #include<cstdio> #include<cmath> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<stack> #define LL long long #define N 100005 #define p 1000000007 using namespace std; inline int read() { int s = 0,w = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); } return s * w; } int to[2 * N],nxt[2 * N],head[2 * N],vis[N],tot; int tmp,res; LL ans = 1; void add(int u,int vis) { to[++tot] = vis; nxt[tot] = head[u]; head[u] = tot; return ; } void dfs(int x) { vis[x] = 1; tmp++; for(int i = head[x]; i; i = nxt[i],res++) if(!vis[to[i]]) dfs(to[i]); } int n,m; void init() { n = read(),m = read(); for(int i = 1; i <= m; i++) { int x = read(),y = read(); add(x,y); add(y,x); } } void solve() { for(int i = 1; i <= n; i++) { if(!vis[i]) { tmp = res = 0; dfs(i); if(tmp > res / 2) ans = ans * tmp % p; else if(tmp == res / 2) ans = ans * 2 % p; else ans = 0; } } printf("%lld",ans); } int main(){ init(); solve(); return 0; }