C - 3 Steps
Time limit : 2sec / Memory limit : 256MB
Score : 500 points
Problem Statement
Rng has a connected undirected graph with N vertices. Currently, there are M edges in the graph, and the i-th edge connects Vertices Ai and Bi.
Rng will add new edges to the graph by repeating the following operation:
- Operation: Choose u and v (u≠v) such that Vertex v can be reached by traversing exactly three edges from Vertex u, and add an edge connecting Vertices u and v. It is not allowed to add an edge if there is already an edge connecting Vertices u and v.
Find the maximum possible number of edges that can be added.
Constraints
- 2≤N≤105
- 1≤M≤105
- 1≤Ai,Bi≤N
- The graph has no self-loops or multiple edges.
- The graph is connected.
Input
Input is given from Standard Input in the following format:
N M
A1 B1
A2 B2
:
AM BM
Output
Find the maximum possible number of edges that can be added.
Sample Input 1
Copy
6 5
1 2
2 3
3 4
4 5
5 6
Sample Output 1
Copy
4
If we add edges as shown below, four edges can be added, and no more.
Sample Input 2
Copy
5 5
1 2
2 3
3 1
5 4
5 1
Sample Output 2
Copy
5
Five edges can be added, for example, as follows:
- Add an edge connecting Vertex 5 and Vertex 3.
- Add an edge connecting Vertex 5 and Vertex 2.
- Add an edge connecting Vertex 4 and Vertex 1.
- Add an edge connecting Vertex 4 and Vertex 2.
- Add an edge connecting Vertex 4 and Vertex 3.
//Atcoder的题目还是有新意啊,可以收获不少
题意: n 个点 m 条边, 组成一个无向连通图,重复操作, 如果 a 点到 b 点距离为 3 ,并且没有连回 a ,就添加一条 a - b 的边。没有自环,问最多能添加几条边。
分析可知,如有图有奇数环,必然可加成完全图
如果图是二分图,则会变成完全二分图,
否则最终变为完全图
二分图dfs染色即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 # define LL long long 4 # define pr pair 5 # define mkp make_pair 6 # define lowbit(x) ((x)&(-x)) 7 # define PI acos(-1.0) 8 # define INF 0x3f3f3f3f3f3f3f3f 9 # define eps 1e-8 10 # define MOD 1000000007 11 12 inline int scan() { 13 int x=0,f=1; char ch=getchar(); 14 while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} 15 while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} 16 return x*f; 17 } 18 inline void Out(int a) { 19 if(a<0) {putchar('-'); a=-a;} 20 if(a>=10) Out(a/10); 21 putchar(a%10+'0'); 22 } 23 # define MX 100005 24 /**************************/ 25 int n,m; 26 vector<int> G[MX]; 27 int clo[MX]; 28 29 bool check() 30 { 31 bool ok=0; 32 for (int i=1;i<=n;i++) 33 { 34 if (G[i].size()>=2) 35 { 36 if (ok) return 1; 37 ok=1; 38 } 39 } 40 return 0; 41 } 42 43 int dfs(int p,int s,int pre) 44 { 45 clo[p] = s%2+1; 46 for (int i=0;i<G[p].size();i++) 47 { 48 int v = G[p][i]; 49 if (v==pre) continue; 50 if (!clo[v]) 51 { 52 if (!dfs(v,s+1,p)) 53 return 0; 54 } 55 else if(clo[v]==clo[p]) return 0; 56 } 57 return 1; 58 } 59 60 int bipartite() 61 { 62 memset(clo,0,sizeof(clo)); 63 if (!dfs(1,1,-1)) return 0; 64 return 1; 65 } 66 67 int main() 68 { 69 while(scanf("%d%d",&n,&m)!=EOF) 70 { 71 for (int i=1;i<=n;i++) G[i].clear(); 72 73 for (int i=1;i<=m;i++) 74 { 75 int x,y; 76 scanf("%d%d",&x,&y); 77 G[x].push_back(y); 78 G[y].push_back(x); 79 } 80 if (!check()) 81 printf("0 "); 82 else if (!bipartite()) 83 printf("%lld ",(LL)n*(n-1)/2-m); 84 else 85 { 86 LL b=0,w=0; 87 for (int i=1;i<=n;i++) 88 { 89 if (clo[i]==1) b++; 90 else w++; 91 } 92 printf("%lld ",b*w-m); 93 } 94 } 95 return 0; 96 }