HDU 5313

来源:互联网 发布:有关健身的软件 编辑:程序博客网 时间:2024/06/03 16:45

要构成最大完全图,就意味着节点二分为两半乘积最大,那么该题目转化为,先对所有联通分量二分匹配,求出每个分量的两个二分值。然后求这些从每个两个里面选一个最终能够构成1-n中的哪些值,然后暴力一下即可。对于从m个二元组中每个选一个数都成最终数字,可以用普通的O(m*n)的背包但本题目n<=10000,用bitset优化背包,即可。

本体自己代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <list>#include <queue>#include <stack>#include <string>#include <set>#include <cmath>#include <bitset>#define clr(a, x) memset(a, x, sizeof a)#define ALL(a) a.begin(), a.end()#define ls (rt<<1)#define rs (ls|1)#define lson l, mid, ls#define rson mid+1, r, rsusing namespace std;typedef long long LL;typedef pair<int, int> pii;const int maxn=10000+100;int n, scc_cnt, col[maxn];int scc[maxn][3];bool d[maxn];vector<int> G[maxn], ans[3];void init(){    scc_cnt=0;    memset(col, 0, sizeof col);    memset(d, 0, sizeof d);    ans[0].clear();    ans[1].clear();    clr(scc, 0);    for(int i=0;i<=n;i++) G[i].clear();}bool dfs(int u){    for(int i=0; i<G[u].size(); i++)    {        int v=G[u][i];        if(col[u]==col[v])return false;        if(!col[v])        {            col[v]=3-col[u];            scc[scc_cnt][col[v]-1]++;            if(!dfs(v))return false;        }    }    return true;} int T, m;int dp(){  typedef bitset<10001> Bitset;        Bitset cur;        cur.set(0);        for(int i=1;i<=scc_cnt;i++) {            int a = scc[i][0], b = scc[i][1];            if(a == 0 && b == 0) continue;            cur = cur << a | cur << b;        }        long long ans = 0;        for(int i=1;i<=n;i++) if(cur[i]){            ans = max((long long )ans, (long long)i * (n-i) - m);        }        cout << ans << endl;        return 0;}int main(){    scanf("%d", &T);    while(T--)    {        scanf("%d%d", &n, &m);        init();        for(int i=0; i<m; i++)        {            int u, v;            scanf("%d%d", &u, &v);            G[u].push_back(v);            G[v].push_back(u);        }        for(int i=1; i<=n; i++)            if(!col[i])            {                col[i]=1;                scc[++scc_cnt][0]++;                dfs(i);            }        dp();    }    return 0;}


附anta代码:

#include <string>#include <vector>#include <algorithm>#include <numeric>#include <set>#include <map>#include <queue>#include <iostream>#include <sstream>#include <cstdio>#include <cmath>#include <ctime>#include <cstring>#include <cctype>#include <cassert>#include <limits>#include <functional>#include <bitset>#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))#if defined(_MSC_VER) || __cplusplus > 199711L#define aut(r,v) auto r = (v)#else#define aut(r,v) __typeof(v) r = (v)#endif#define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it)#define all(o) (o).begin(), (o).end()#define pb(x) push_back(x)#define mp(x,y) make_pair((x),(y))#define mset(m,v) memset(m,v,sizeof(m))#define INF 0x3f3f3f3f#define INFL 0x3f3f3f3f3f3f3f3fLLusing namespace std;typedef vector<int> vi; typedef pair<int,int> pii; typedef vector<pair<int,int> > vpii; typedef long long ll;template<typename T, typename U> inline void amin(T &x, U y) { if(y < x) x = y; }template<typename T, typename U> inline void amax(T &x, U y) { if(x < y) x = y; }struct UnionFind {    vector<int> data;    void init(int n) { data.assign(n, -1); }    bool unionSet(int x, int y) {        x = root(x); y = root(y);        if(x != y) {            if(data[y] < data[x]) swap(x, y);            data[x] += data[y]; data[y] = x;        }        return x != y;    }    bool findSet(int x, int y) { return root(x) == root(y); }    int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }    int size(int x) { return -data[root(x)]; }};int main() {    int T;    scanf("%d", &T);    rep(ii, T) {        int n, m;        scanf("%d%d", &n, &m);        UnionFind uf, uf2;        uf.init(n);        uf2.init(n * 2);        rep(i, m) {            int u, v;            scanf("%d%d", &u, &v), -- u, -- v;            uf.unionSet(u, v);            uf2.unionSet(u, n + v);            uf2.unionSet(n + u, v);        }        vi cnt1(n, 0), cnt2(n, 0);        rep(i, n) {            if(uf2.findSet(i, uf.root(i)))                ++ cnt1[uf.root(i)];            else                ++ cnt2[uf.root(i)];        }        typedef bitset<10001> Bitset;        Bitset cur;        cur.set(0);        rep(i, n) {            int a = cnt1[i], b = cnt2[i];            if(a == 0 && b == 0) continue;            cur = cur << a | cur << b;        }        ll ans = 0;        rer(i, 0, n) if(cur[i])            amax(ans, (ll)i * (n-i) - m);        cout << ans << endl;    }    return 0;}



0 0
原创粉丝点击