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 题意: 给出一张不一定合法的染色图,每次可以交换相邻两点的颜色,问最少多少次能使染色图合法 合法的染色图相邻点的颜色不能相同 题解: 首先要确定 ...
随机推荐
- ubuntu server安装kvm
参考资料: 1. https://help.ubuntu.com/community/KVM 2.http://wiki.ubuntu.org.cn/Kvm%E6%95%99%E7%A8%8B 3.h ...
- unix awk手册读书笔记
http://note.youdao.com/noteshare?id=9ac76eb63a53ac000f7814454642d2b0
- bzoj 3714 [PA2014]Kuglarz 最小生成树
[PA2014]Kuglarz Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1335 Solved: 672[Submit][Status][Di ...
- ZooKeeper翻译(一)
欢迎来到Apache ZooKeeper的世界 Apache Zookeeper是一个为了开发和维护一个开源的服务的一个尝试,这个服务使高可用的分布式协作成为可能. ZooKeeper是什么? Zoo ...
- Git版本回退的最佳方式
使用git开发的过程中,存在误提交的时候怎么办呢?不用慌张,强大的git提供了两种版本回退的方式,可以让你恢复提交之前的内容: 方式一:reset(不推荐) 通过reset的方式,把head指针指向之 ...
- MVP应用在android app上
使用MVP模式来解耦activity中业务代码和界面代码.在activity中,将其中的业务抽象到presenter层:将其中的界面代码抽象到View层. MVP模式: 一个软件被划分成三层,View ...
- [LA3135]node形式的优先队列
n个触发器,每个触发器每period秒就产生一个编号为qnum的事件,求前k个事件. n<=1000 k<=10000 node形式的优先队列 主要在于重载小于号,确定优先顺序. #in ...
- 【BZOJ】2196: [Usaco2011 Mar]Brownie Slicing
[题意]给定n*m的数字矩阵,要求横着切A-1刀,对每块再分别竖着切B-1刀,是最小子矩阵最大. [算法]二分+贪心 [题解]还记得提高组2015跳石头吗?这道题做法一致,只不过拓展到二维而已. 二分 ...
- csc_滤镜filter和实现透明的两种方式
有这样一个需求,给一个地图实现半透明效果. 使用css滤镜属性可以实现:filter. 下面是属性的所以值 filter: none | blur() | brightness() | contras ...
- 2017-2018-1 20179205《Linux内核原理与设计》第九周作业
<Linux内核原理与设计>第九周作业 视频学习及代码分析 一.进程调度时机与进程的切换 不同类型的进程有不同的调度需求,第一种分类:I/O-bound 会频繁的进程I/O,通常会花费很多 ...