码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5313 Bipartite Graph (二分图着色,dp) TLE!!!

时间:2015-07-26 15:35:43      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:

 

 

 

题意:Soda有一个$n$个点$m$条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的.

思路:二分图着色这个简单,主要是dp,还有时间限制。我觉得应该是找出所有连通分量,每个连通分量两边的点数存起来,后面统一进行DP。但是!!时间仅有1s,而且还100个例子,就是说大概要在100万的复杂度才行,可是有1万个点,当m=5000时,这就不行。

 

  我不懂这道题如何下手才能保证一定正确且不超时,应该优化得很厉害~

 

贴一个我认为对的TLE代码:

 

技术分享
 1 #include <bits/stdc++.h>
 2 #define LL long long
 3 #define pii pair<int,int>
 4 #define INF 0x7f7f7f7f
 5 using namespace std;
 6 const int N=10100;
 7 vector<int> vect[N];
 8 int col[N];
 9 int set1, set2;
10 
11 void color(int u, int c)
12 {
13     col[u]=c;
14     if(col[u]==1) set1++;//统计两边的数量
15     else        set2++;
16 
17     for(int i=0; i<vect[u].size(); i++)
18     {
19         int t=vect[u][i];
20         if(!col[t])   //没色
21             color(t, 3-col[u] );
22     }
23 }
24 
25 
26 bitset<N/2> dp[N];
27 int s1[N/2],s2[N/2];
28 int cal(int n, int m)
29 {
30     if(m==n/2*(n-n/2) ) return 0;
31     for(int i=0; i<=n; i++) vect[i].clear(), dp[i].reset();
32 
33     memset(col, 0, sizeof(col));
34     int ans=0, k=0;
35     for(int i=1; i<=n; i++)
36     {
37         if(!col[i])
38         {
39             set1=set2=0;
40             color(i, 1);
41 
42             s1[k]=set1;//每个连通分量两边的点数
43             s2[k++]=set2;
44         }
45     }
46 
47     if(k==1)    return s1[0] * s2[0] - m;//连通图
48     dp[0][0]=1;
49     for(int i=0; i<k; i++)//在这进行DP,尽量使得两边的点数平衡
50     {
51         ans=0;
52         set1=s1[i];
53         set2=s2[i];
54 
55         for(int j=n/2; j>=set1; j--)
56             if( dp[i][j-set1] )    dp[i+1][j]=1,ans=max(ans,j);
57 
58         for(int j=n/2; j>=set2; j--)
59             if( dp[i][j-set2] )    dp[i+1][j]=1,ans=max(ans,j);
60     }
61     return ans*(n-ans)-m;
62 }
63 
64 
65 int main()
66 {
67     //freopen("input.txt", "r", stdin);
68     int n, m, t, p, q, a, b;
69     cin>>t;
70 
71     while(t--)
72     {
73         scanf("%d%d",&n,&m);
74         for(int i=0; i<m; i++)
75         {
76             scanf("%d%d",&a,&b);
77             vect[a].push_back(b);
78             vect[b].push_back(a);
79         }
80         printf("%d\n",cal(n, m));
81     }
82     return 0;
83 }
AC代码

 

HDU 5313 Bipartite Graph (二分图着色,dp) TLE!!!

标签:

原文地址:http://www.cnblogs.com/xcw0754/p/4677721.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!