考验代码能力的题目,感觉网络流一要求输出方案我就写的丑

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的更多相关文章

  1. HDU5740 Glorious Brilliance【最短路 KM匹配】

    HDU5740 Glorious Brilliance 题意: 给出一张不一定合法的染色图,每次可以交换相邻两点的颜色,问最少多少次能使染色图合法 合法的染色图相邻点的颜色不能相同 题解: 首先要确定 ...

随机推荐

  1. [ZJOI2010]排列计数 (组合计数/dp)

    [ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...

  2. Sql Server 2008 R2 数据库脚本导出方法

    经常忘记怎么搞,截几张图记录一下. 1 选中要导出的数据库,右键—>任务—>生成脚本 2 3 4 查看保存的脚本

  3. CSS3知识之阴影box-shadow

    一.定义和用法 box-shadow 属性向框添加一个或多个阴影. box-shadow: h-shadow v-shadow blur spread color inset; h-shadow   ...

  4. 洛谷 P1044 栈

    题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). 栈的重要性不言自明,任何 ...

  5. Spark的Shuffle过程介绍

    Spark的Shuffle过程介绍 Shuffle Writer Spark丰富了任务类型,有些任务之间数据流转不需要通过Shuffle,但是有些任务之间还是需要通过Shuffle来传递数据,比如wi ...

  6. HDU5852 Intersection is not allowed!

    There are K pieces on the chessboard. The size of the chessboard is N*N. The pieces are initially pl ...

  7. bzoj 4773: 负环——倍增

    Description 在忘记考虑负环之后,黎瑟的算法又出错了.对于边带权的有向图 G = (V, E),请找出一个点数最小的环,使得 环上的边权和为负数.保证图中不包含重边和自环. Input 第1 ...

  8. 【转载】VS2013安装需要IE10

    因为需要移动办公,需要给笔记本搭建编程环境.安装VS2013时遇到了小麻烦,提示我,需要安装IE10. 然后我很听话的按照提供的超链接,到了官网,下载了最新的IE11,然后安装,结果告诉我下载的IE版 ...

  9. Linux系统网络基础知识及配置

    一:DNS(domain name system)简介 DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而 ...

  10. js函数定义方法

    1.函数声明 其语法为 function functionName(){ //函数体 } 首先是function关键字,然后是函数名,其重要特征是函数声明提升,即在执行代码之前会先读取函数声明,使其在 ...