Test instructions: N points m-edge, two endpoints of each edge are known, to make up the maximum number of edges that a complete binary graph can add;
Reference: http://blog.csdn.net/acmhonor/article/details/47072399
Idea: Not a two-figure problem ...
N points constitute a complete two-dimensional graph is, the difference between the two sides of the minimum number of edges (X+y=n, Max (x*y));
That is, given some edges, the requirement is that the number of points in the two sets of the smallest difference in the case;
First of all the points in each Unicom block, consider the number of isolated points, through the greedy to achieve pruning;
Non-greedy situation using backpack, backpack capacity of N/2, the introduction of the optimal solution;
#include <cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespacestd;intt,n,m,top,minnn;intsum1,sum2,num,num1,num2;intsta[2][50010];intdp[500010];structnode{intTo,next;} g[500010];inthead[500010],vis[500010];voidAddintUintv) {g[top].to=v; G[top].next=Head[u]; Head[u]=top++;}voidDfsintx) { if(vis[x]==-1) Vis[x]=0; for(inti=head[x];i!=-1; i=G[i].next) { intv=g[i].to; if(vis[v]==-1) {Vis[v]=1-Vis[x]; if(vis[v]==0) sum1++; Elsesum2++; DFS (v); } }}intMain () {inti,j,k,a,b; while(SCANF ("%d", &t)! =EOF) { while(t--) {memset (head,-1,sizeof(head)); memset (Vis,-1,sizeof(VIS)); scanf ("%d%d",&n,&m); Top=0; sum1=0; sum2=0; for(i=0; i<m;i++) {scanf ("%d%d",&a,&b); Add (A, b); Add (B,a); } Top=0; num=0; num1=num2=0; for(i=1; i<=n;i++) { if(vis[i]==-1) {sum1=1; sum2=0; DFS (i); sta[0][top]=sum1; sta[1][top++]=sum2; if(sum2==0) {num++; } Else if(num1<num2) {NUM1+=Max (SUM1,SUM2); Num2+=min (sum1,sum2); } Else{NUM1+=min (sum1,sum2); Num2+=Max (SUM1,SUM2); } } } if(ABS (NUM1-NUM2) <=num) {printf ("%d\n", ((n+1)/2) * (n/2)-m); Continue; } intminn=-1; for(i=0; i<top;i++) { intcn1=0; for(j=n/2; j>=sta[0][i]| | j>=sta[1][i];j--){ if(j>=sta[0][i]&&ans<dp[j-sta[0][i]]+sta[0][i]&&dp[j-sta[0][i]]>=Minn)//each unicom block must choose an ans=dp[j-sta[0][i]]+sta[0][i]; if(j>=sta[1][i]&&ans<dp[j-sta[1][i]]+sta[1][i]&&dp[j-sta[1][i]]>=Minn) ans=dp[j-sta[1][i]]+sta[1][i]; DP[J]=ans; if(ans&&ans<=minnn) minnn=ans; } Minn=minnn; } printf ("%d\n", dp[n/2]* (n-dp[n/2])-m); } } return 0;}
HDU 5313 bipartite Graph (dfs+ backpack)