hdu 5740(构造,KM)
来源:互联网 发布:ps二维码源码 编辑:程序博客网 时间:2024/05/19 18:11
#include <bits/stdc++.h>using namespace std;#define LL long long#define pii pair<int, int>#define MP make_pair#define ls i << 1#define rs ls | 1#define md (ll + rr >> 1)#define inf 0x3f3f3f3f#define mod 1000000007#define N 520#define M 500020int getint(){ int ret = 0; char ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9') ret = ret * 10 + ch - '0', ch = getchar(); return ret;}int n, m, ans;int fst[N], vv[M], nxt[M], e;int c1, c2, sz, col[N];int dis[N][N], pre[N][N];char s[N];bool vis[N];vector<int> node;void init(){ memset(fst, -1, sizeof fst); e = 0;}void add(int u, int v){ vv[e] = v, nxt[e] = fst[u], fst[u] = e++;}bool bin_color(int u){ c1 += col[u] == 1; c2 += s[u] == '1'; ++sz; for(int i = fst[u]; ~i; i = nxt[i]){ int v = vv[i]; if(!col[v]){ col[v] = 3 - col[u]; if(!bin_color(v)) return 0; } else if(col[v] == col[u]) return 0; } return 1;}void bfs(int s, int d[], int pre[]){ queue<int> q; q.push(s); d[s] = 0; pre[s] = s; while(!q.empty()){ int u = q.front(); q.pop(); for(int i = fst[u]; ~i; i = nxt[i]){ int v = vv[i]; if(d[v] > d[u] + 1){ d[v] = d[u] + 1; pre[v] = u; q.push(v); } } }}bool check(){ for(int i = 1; i <= n; ++i){ if(!col[i]){ col[i] = 1; c1 = c2 = sz = 0; if(!bin_color(i)) return 0; if(min(sz - c1, c1) != min(sz - c2, c2)) return 0; } } return 1;}void mark(int u){ vis[u] = 1; node.push_back(u); for(int i = fst[u]; ~i; i = nxt[i]){ int v = vv[i]; if(!vis[v]) mark(v); }}int nu, val[N][N];int lx[N], ly[N], link[N];bool visx[N], visy[N];vector<int> match[2];int slack[N];bool dfs(int u){ visx[u] = 1; for(int i = 1; i <= nu; ++i){ if(visy[i]) continue; int t = lx[u] + ly[i] - val[u][i]; if(t == 0){ visy[i] = 1; if(link[i] == -1 || dfs(link[i])){ link[i] = u; return 1; } } else if(slack[i] > t) slack[i] = t; } return 0;}int km(){ memset(ly, 0, sizeof ly); for(int i = 1; i <= nu; ++i){ lx[i] = -inf; for(int j = 1; j <= nu; ++j) lx[i] = max(lx[i], val[i][j]); } memset(link, -1, sizeof link); for(int i = 1; i <= nu; ++i){ memset(slack, 0x3f, sizeof slack); while(1){ memset(visx, 0, sizeof visx); memset(visy, 0, sizeof visy); if(dfs(i)) break; int d = inf; for(int i = 1; i <= nu; ++i) if(!visy[i] && slack[i] < d) d = slack[i]; for(int i = 1; i <= nu; ++i) if(visx[i]) lx[i] -= d; for(int i = 1; i <= nu; ++i){ if(visy[i]) ly[i] += d; else slack[i] -= d; } } } int ret = 0; int cnt = 0; for(int i = 1; i <= nu; ++i){ if(link[i] != -1 && val[link[i]][i] != -inf) ++cnt, ret += val[link[i]][i]; } if(cnt < nu) return -1; return -ret;}vector<int> ll[2];int gao(int w){ ll[0].clear(); ll[1].clear(); c1 = c2 = 0; for(int i = 0; i < node.size(); ++i){ int v = node[i]; c1 += col[v] == 2; c2 += s[v] == '1'; if(s[v] - '0' != col[v] - 1){ ll[s[v]-'0'].push_back(v); } } if(c1 != c2) return inf; nu = ll[0].size(); for(int i = 0; i < nu; ++i) for(int j = 0; j < nu; ++j) val[i+1][j+1] = -dis[ll[0][i]][ll[1][j]]; int ret = km(); for(int i = 1; i <= nu; ++i){ int v = ll[1][i-1]; match[w].push_back(v); match[w].push_back(ll[0][link[i]-1]); } return ret;}vector<pii > ff, f;void get(int u, int v){ int t = v; while(v != u){ t = v; ff.clear(); while(t != u && s[t] == s[v]) ff.push_back(MP(t, pre[u][t])), t = pre[u][t]; for(int i = ff.size() - 1; i >= 0; --i){ swap(s[ff[i].first], s[ff[i].second]); f.push_back(ff[i]); } v = t; }}void build(vector<int> g){ for(int i = 0; i < g.size(); i += 2){ int u = g[i], v = g[i+1]; get(u, v); }}int main(){ int cas; scanf("%d", &cas); while(cas--){ scanf("%d%d", &n, &m); scanf("%s", s + 1); init(); for(int i = 1; i <= m; ++i){ int u, v; u = getint(), v = getint(); add(u, v), add(v, u); } for(int i = 1; i <= n; ++i) col[i] = vis[i] = 0; if(!check()){ puts("-1"); continue; } for(int i = 0; i <= n; ++i) for(int j = 0; j <= n; ++j) dis[i][j] = inf; for(int i = 1; i <= n; ++i) bfs(i, dis[i], pre[i]); ans = 0; f.clear(); for(int i = 1; i <= n; ++i){ if(!vis[i]){ match[0].clear(); match[1].clear(); node.clear(); mark(i); if(node.size() == 1) continue; int t1 = gao(0); for(int j = 0; j < node.size(); ++j) col[node[j]] = 3 - col[node[j]]; int t2 = gao(1); if(t1 <= t2){ ans += t1; build(match[0]); } else{ ans += t2; build(match[1]); } } } printf("%d\n", ans); for(int i = 0; i < f.size(); ++i) printf("%d %d\n", f[i].first, f[i].second); } return 0;}
0 0
- hdu 5740(构造,KM)
- HDU 3718 KM
- HDU 2255 KM算法
- hdu 3488 Tour (KM)
- hdu 3718 (KM)
- hdu 3722 (KM)
- hdu 3395 (KM裸题)
- tour hdu 3488 KM
- hdu 1533KM算法
- hdu 1853 KM算法
- hdu 3488 Tour KM
- HDU 2426 KM
- hdu 2813(KM+map)
- HDU 2853 Assignment KM
- 【HDU 4862】Jump【KM】
- HDU 3718 KM算法
- HDU 2255 (KM()算法)
- HDU-2255(KM算法)
- Hadoop2.2.0集群搭建
- 强执行力领导者的七大特质
- Ubuntu下搭建PIXHAWK开发环境
- 配置Jstl的Maven依赖
- 溢出警告
- hdu 5740(构造,KM)
- ARM WFI和WFE指令
- 每天进步一点点——负载均衡之反向代理
- 【工具】Visual Studio 2015的离线MSDN Microsoft help viewer 2.2 注册表修改
- 黑马程序员:平均薪资近12K,Android续写“刷薪”记录!
- 文章标题
- Where Amazing Happens
- poj 3254 Corn Fields
- 类似微型发朋友有圈时的弹出框