hdu5740
考验代码能力的题目,感觉网络流一要求输出方案我就写的丑
http://www.cnblogs.com/duoxiao/p/5777632.html 官方题解写的很详细
因为如果一个点染色确定后,整个图的染色也就确定了;
对于两个点u和v, 令它们之间的最短路是dis(u,v), 那么交换它们两个颜色的最少步数是dis(u,v), 且存在一种交换序列不会破坏其它节点的颜色
这是两个突破口
我的一个WA的地方在于:构造方案时没有把路径上的颜色交换……
#include<bits/stdc++.h>
#define mp make_pair
#define pi pair<int,int>
using namespace std;
const int inf=1e9+;
struct node{int po,next,flow,cost;} e[];
pi a[];
vector<pi> tmp;
vector<int> g[],s[];
int f[][],from[][],q[],pre[],cur[],d[],p[],mark[],cl[],rc[];
bool v[];
int n,m,len,t,ans,s1,s0;
void add(int x,int y,int f,int c)
{
e[++len].po=y;
e[len].flow=f;
e[len].cost=c;
e[len].next=p[x];
p[x]=len;
} void build(int x,int y, int f, int c)
{
add(x,y,f,c);
add(y,x,,-c);
} bool spfa()
{
int f=,r=;
for (int i=; i<=t; i++) d[i]=inf;
memset(v,,sizeof(v));
d[]=; q[]=;
while (f<=r)
{
int x=q[f++];
v[x]=;
for (int i=p[x]; i!=-; i=e[i].next)
{
int y=e[i].po;
if (e[i].flow&&d[x]+e[i].cost<d[y])
{
d[y]=d[x]+e[i].cost;
pre[y]=x; cur[y]=i;
if (!v[y])
{
q[++r]=y;
v[y]=;
}
}
}
}
return d[t]<inf;
} int mincost()
{
int s=;
while (spfa())
{
s+=d[t];
for (int i=t; i; i=pre[i])
{
int j=cur[i];
e[j].flow--;
e[j^].flow++;
}
}
return s;
} void bfs(int st)
{
memset(v,,sizeof(v));
for (int i=; i<=n; i++) f[st][i]=inf;
int h=,r=; q[]=st; v[st]=; f[st][st]=;
while (h<=r)
{
int x=q[h++];
for (int i=; i<g[x].size(); i++)
{
int y=g[x][i];
if (!v[y])
{
f[st][y]=f[st][x]+;
from[st][y]=x;
v[y]=;
q[++r]=y;
}
}
}
} bool get(int x,int w)
{
mark[x]=w; s[w].push_back(x);
if (rc[x]==) s1++; else s0++;
for (int i=; i<g[x].size(); i++)
{
int y=g[x][i];
if (mark[y]==-) get(y,w^);
else if (mark[y]==mark[x]) return ;
}
return ;
} void path(int st,int en,int w)
{
int x=en,r=; q[]=en;
while (x!=st)
{
x=from[st][x];
q[++r]=x;
if (cl[x]^cl[q[]])
{
for (int i=r; i>; i--)
{
tmp.push_back(mp(q[i],q[i-]));
swap(cl[q[i]],cl[q[i-]]);
}
r=; q[]=x;
}
}
} void way(int w)
{
for (int i=; i<=n; i++) cl[i]=rc[i];
for (int i=; i<=len; i+=)
{
int y=e[i].po,x=e[i^].po;
if (x&&y<t&&e[i].flow==) path(x,y,w);
}
} void graph(int w)
{
len=-; memset(p,,sizeof(p));
for (int i=; i<s[].size(); i++)
{
int x=s[][i];
if (rc[x]^w) build(,x,,);
}
for (int i=; i<s[].size(); i++)
{
int x=s[][i];
if (rc[x]^w) continue;
build(x,t,,);
for (int j=; j<s[].size(); j++)
{
int y=s[][j];
if (rc[y]^w) build(y,x,,f[y][x]);
}
}
} bool check(int x)
{
s1=s0=;
s[].clear(); s[].clear();
if (!get(x,)) return ;
if (s1+s0==) return ;
if (s0!=s[].size()&&s0!=s[].size()) return ;
int ans1=inf,ans2=inf;
if (s0==s[].size())
{
graph(); ans1=mincost();
tmp.clear(); way();
}
if (s1==s[].size())
{
graph();
ans2=mincost();
}
if (ans1==inf&&ans2==inf) return ;
if (ans2<ans1)
{
tmp.clear(); way();
for (int i=; i<tmp.size(); i++)
a[++ans]=tmp[i];
}
else {
for (int i=; i<tmp.size(); i++)
a[++ans]=tmp[i];
}
return ;
} int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d%d\n",&n,&m);
for (int i=; i<=n; i++) g[i].clear();
for (int i=; i<=n; i++)
{
char ch=getchar();
rc[i]=ch-'';
}
for (int i=; i<=m; i++)
{
int x,y;
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
for (int i=; i<=n; i++) bfs(i);
memset(mark,,sizeof(mark));
bool ff=; ans=; t=n+;
for (int i=; i<=n; i++)
if (mark[i]==-)
{
ff&=check(i);
if (!ff) break;
} if (!ff) puts("-1");
else {
printf("%d\n",ans);
for (int i=; i<=ans; i++)
printf("%d %d\n",a[i].first,a[i].second);
}
}
}
hdu5740的更多相关文章
- HDU5740 Glorious Brilliance【最短路 KM匹配】
HDU5740 Glorious Brilliance 题意: 给出一张不一定合法的染色图,每次可以交换相邻两点的颜色,问最少多少次能使染色图合法 合法的染色图相邻点的颜色不能相同 题解: 首先要确定 ...
随机推荐
- C++之内部类与外部类(嵌套类)及友元
转载于:http://www.cnblogs.com/qzhforthelife/p/3226885.html 先上代码: class Outer { public: Outer(){m_outerI ...
- Codeforces Round #396 (Div. 2) A B C D 水 trick dp 并查集
A. Mahmoud and Longest Uncommon Subsequence time limit per test 2 seconds memory limit per test 256 ...
- http学习 - 缓存
对缓存的理解更加深刻,缓存有一个过期时间,现在用的比较多的是 max-age,以前使用 expirt之类的, 然后就是需要向服务器验证是否是最新的,如果不是最新的则需要更新.
- [USACO09DEC] Cow Toll Paths
https://www.luogu.org/problem/show?pid=2966 题目描述 Like everyone else, FJ is always thinking up ways t ...
- uva 12325 Zombie's Treasure Chest
https://vjudge.net/problem/UVA-12325 题意: 一个箱子,体积为N 两种宝物,体积为S1.S2,价值为V1.V2,数量无限 最多装多少价值的宝物 数据范围:2^32 ...
- 三星 C7恢复 出厂设置
http://jingyan.baidu.com/article/c14654134f0fd20bfcfc4c1e.html
- [hdu2460]network(依次连边并询问图中割边数量) tarjan边双联通分量+lca
题意: 给定一个n个点m条边的无向图,q个操作,每个操作给(x,y)连边并询问此时图中的割边有多少条.(连上的边会一直存在) n<=1e5,m<=2*10^5,q<=1e3,多组数据 ...
- UIImageView与UIScrollView的关系图
UIImageView与UIScrollView的关系图 https://www.evernote.com/shard/s227/sh/0af9f23c-08e6-4be6 ...
- TDD随想录
TDD随想录 谨以本文献给TDD的开创者与传播者 本文纯属个人经历,如有雷同纯属巧合 我从不觉得自己是一个好的程序员,甚至可能连合格都谈不上,不过在内心深处我却渴望着在编程这件事上获得成功. 可惜每次 ...
- JAVA 非对称加密算法RSA
非对称加密算法 RSA过程 : 以甲乙双方为例 1.初始化密钥 构建密钥对,生成公钥.私钥保存到keymap中 KeyPairGenerator ---> KeyPair --> RSAP ...