hdu5313--Bipartite Graph

来源:互联网 发布:乌鱼子淘宝的价格 编辑:程序博客网 时间:2024/06/05 23:55

题目链接:点击打开链接

问最多能加多少边为完全二分图,左右两侧有ln,rn个点,那么完全二分图有ln*rn条边,首先应该建图后,按照黑白染色的方式,分成一个二分图,分为二分图后,重新遍历边,找到在二分图中有作用的边的条数num,因为n个点是固定的,二分图中存在作用的边也是固定,如果想要加的边尽量多,就只能让二分图的总边数尽量的多,也就是让两边的点数尽量的接近,这是就用到了,之前没有任何边连接的点,因为它们可以加入左侧或右侧,通过它们让左右两侧的点数尽量的接近,这样ln*rn-num就是最多的加边数了。

#include <cstdio>#include <cstring>#include <queue>#include <set>#include <vector>#include <cmath>#include <map>#include <stack>#include <algorithm>using namespace std ;#define LL __int64#define INF 0x3f3f3f3f#define PI acos(-1.0)const int mod = 1e9+7 ;const double eqs = 1e-9 ;struct node{    int u , v ;    int next ;}edge[210000] ;int head[11000] , cnt ;int a[11000] ;void add(int u,int v) {    edge[cnt].u = u ; edge[cnt].v = v ;    edge[cnt].next = head[u] ; head[u] = cnt++ ;    edge[cnt].u = v ; edge[cnt].v = u ;    edge[cnt].next = head[v] ; head[v] = cnt++ ;}void dfs(int u) {    int i , v ;    for(i = head[u] ; i !=-1 ; i = edge[i].next) {        v = edge[i].v ;        if( a[v] != -1 ) continue ;        a[v] = 1 - a[u] ;        dfs(v) ;    }}int main() {    int t , n , m , l_num , r_num;    int u , v , i , j ;    scanf("%d", &t) ;    while(t--) {        scanf("%d %d", &n, &m) ;        memset(head,-1,sizeof(head)) ;        cnt = l_num = r_num = 0 ;        while( m-- ) {            scanf("%d %d", &u, &v) ;            add(u,v) ;        }        memset(a,-1,sizeof(a)) ;        for(i = 1 ; i <= n ; i++) {            if( a[i] == -1 && head[i] != -1 ) {                a[i] = 0 ;                dfs(i) ;            }        }        int num = 0 ;        for(u = 1 ; u <= n ; u++) {            if( a[u] == 1 ) r_num++ ;            else if( a[u] == 0 ) l_num++ ;            if( a[u] ) continue ;            for(j = head[u] ; j != -1 ; j = edge[j].next) {                v = edge[j].v ;                if( a[v] == 0 ) continue ;                num++ ;            }        }        int k1 , k2 , c = n-l_num-r_num ;        k1 = max(l_num,r_num) ;        k2 = min(l_num,r_num) ;        if( k1 >= k1 + c ) {            k1 += c ;        }        else {            c -= k1-k2 ;            k2 = k1 ;            k1 += c/2 ;            k2 += c-c/2 ;        }        printf("%d\n", k1*k2-num ) ;    }    return 0 ;}


0 0
原创粉丝点击