codeforces 789D. Weird journey
题目链接:http://codeforces.com/contest/789/problem/D
题意:给你n个城市,然后有m条路,这m条路不相同,存在自环。现在要你走m-2条路两遍,2条路一遍,访问这m条路包含的城市。问你有多少种方法。
分析:当时看到走两遍,脑子里就想到的是把所有路都添加两遍,然后删去一部分,使得走完所有路,以为要dfs。但是仔细想的话,我要想把路全走了,好比就是有一个或两个大圈,然后有两条是独立的路。这个仔细想一下应该可以理解。因为只有路中有大环,你才可以走两遍走出来。那么我就可以1.删除两个自环路,使得我的图变成一个大环,每两个点都有两条路2.删除一个自环路和一个普通路,然后形成一个单路和大环3.删除两个相邻的路,形成两个单独的路和大环。注意考虑m条路使得包含的点联通。还有就是开longlongQAQ。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 long long a[1000005]; 5 int fx[1000005]; 6 int vis[1000005]; 7 int n,m,u,v; 8 void init(){ 9 for(int i=1;i<=n;i++){ 10 fx[i]=i; 11 } 12 } 13 int findx(int x){ 14 if(fx[x]==x) return x; 15 else return fx[x]=findx(fx[x]); 16 } 17 void unit(int x,int y){ 18 int xx=fx[x],yy=fx[y]; 19 fx[xx]=fx[yy]; 20 } 21 int main() { 22 ios_base::sync_with_stdio(0); 23 cin.tie(0); 24 memset(a,0,sizeof(a)); 25 memset(vis,0,sizeof(vis)); 26 cin>>n>>m; 27 init(); 28 long long quan=0,edge=0,num=n-1; 29 for(int i=1;i<=m;i++){ 30 cin>>u>>v; 31 if(u==v) { 32 quan++; 33 } 34 else { 35 edge++; 36 a[u]++; 37 a[v]++; 38 if(findx(u)!=findx(v)){ 39 unit(u,v); 40 num--; 41 } 42 } 43 vis[u]=1; 44 vis[v]=1; 45 } 46 long long result=0; 47 result+=quan*(quan-1)/2+quan*edge; 48 for(int i=1;i<=n;i++){ 49 result+=a[i]*(a[i]-1)/2; 50 } 51 for(int i=1;i<=n;i++){ 52 if(vis[i]!=1){ 53 num--; 54 } 55 } 56 if(num!=0){ 57 cout<<0<<endl; 58 } 59 else cout<<result<<endl; 60 61 return 0; 62 }