题意:给定一个网格,一些格子是障碍不用管,剩余的格子是城市,你可以修建铁路,铁路的形状可以是直的或者弯的,也就是说可以以这个点为节点连接它四联通的其中两个方块。要求用一个或多个环来覆盖所有城市。对于有些关键点,如果这里是直轨道,会付出1的代价,如果不能覆盖,输出-1,否则输出最小代价。

这次该最小费用流了。x先考虑怎么判断有无解。很明显,既然是棋盘,想不染色不二分图都难。染成黑白后,对于黑点,S向其连2,黑点向周围的白点连1,白点向T连2,判断是否满流就好了。那么怎么计算代价呢?我们发现,如果要付出代价,那么一定是两个开口都给了同一列或者同一行,为了对此限制,我们拆点,分别管辖行和列。

如果这个点是黑关键点,我们向行对应的分身连一个容量1,费用0的边,再连一个容量1,费用1的边,表示如果只用一条边,不会产生费用,否则产生两条边的费用。列的话同理。

白关键点就不赘述了,其实也就是相较于反了一下。对于普通点,直接相对应的两个点分别连(2,0)就好了(因为没有限制),然后黑连向对应的白就好了。

跑费用流,不满流无解,满流输出费用即可。

 #include<bits/stdc++.h>
using namespace std;
#define INF 1e9
#define N 5005
#define id(i,j) ((i-1)*m+j)
int n,m,TOT,S,T,P,head[N],d[N],a[N],p[N],cnt;
bool vis[N];
queue<int>q;
char field[N][N];
inline int read(){
int x=,f=; char a=getchar();
while(a<'' || a>'') {if(a=='-') f=-; a=getchar();}
while(a>='' && a<='') x=x*+a-'',a=getchar();
return x*f;
}
struct edges{
int fr,to,cap,flow,cost,next;
}e[*N]; inline void insert(int u,int v,int f,int c){
e[cnt]=(edges){u,v,f,,c,head[u]};head[u]=cnt++;
e[cnt]=(edges){v,u,,,-c,head[v]};head[v]=cnt++;
}
inline bool spfa(){
memset(d,0x3f,sizeof(d));
d[S]=; a[S]=INF; q.push(S);
while(!q.empty()){
int x=q.front(); q.pop(); vis[x]=;
for(int i=head[x];i>=;i=e[i].next)
if(d[e[i].to]>d[x]+e[i].cost && e[i].flow<e[i].cap){
d[e[i].to]=d[x]+e[i].cost; p[e[i].to]=i;
a[e[i].to]=min(a[x],e[i].cap-e[i].flow);
if(!vis[e[i].to]) vis[e[i].to]=,q.push(e[i].to);
}
}
return d[T]<INF;
}
inline int mincf(){
int u=T;
while(u!=S){
e[p[u]].flow+=a[T];
e[p[u]^].flow-=a[T];
u=e[p[u]].fr;
}
TOT-=a[T];
return a[T]*d[T];
} int main(){
n=read(); m=read();
for(int i=;i<=n;i++)
scanf("%s",field[i]+);
S=; T=*n*m+; P=n*m; TOT=;
memset(head,-,sizeof(head));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
if(field[i][j]=='w') continue;
if((i+j)%==){
insert(S,id(i,j),,); TOT+=;
if(field[i][j]!='C') insert(id(i,j),id(i,j)+*P,,),insert(id(i,j),id(i,j)+P,,);
else {
insert(id(i,j),id(i,j)+P,,); insert(id(i,j),id(i,j)+P,,);
insert(id(i,j),id(i,j)+*P,,); insert(id(i,j),id(i,j)+*P,,);
}
if(j-> && field[i][j-]!='w') insert(id(i,j)+P,id(i,j-)+P,,);
if(j+<=m && field[i][j+]!='w' ) insert(id(i,j)+P,id(i,j+)+P,,);
if(i-> && field[i-][j]!='w') insert(id(i,j)+*P,id(i-,j)+*P,,);
if(i+<=n && field[i+][j]!='w') insert(id(i,j)+*P,id(i+,j)+*P,,);
}else{
insert(id(i,j),T,,);
if(field[i][j]!='C') insert(id(i,j)+*P,id(i,j),,),insert(id(i,j)+P,id(i,j),,);
else{
insert(id(i,j)+P,id(i,j),,); insert(id(i,j)+P,id(i,j),,);
insert(id(i,j)+*P,id(i,j),,); insert(id(i,j)+*P,id(i,j),,);
}
}
}
int ans=;
while(spfa()) ans+=mincf();
if(TOT) ans=-;
printf("%d\n",ans);
}

Topcoder SRM570 900 CurvyonRails的更多相关文章

  1. Topcoder SRM570 D1L3 CurvyonRails

    几个样例: 5 5wCCwwwCC....w......www..wReturns: 0 3 3C.w....C.Returns: 1 21 20CC..CCCw.CwC..CC.w.CC.CCCwC ...

  2. Topcoder口胡记 SRM 562 Div 1 ~ SRM 599 Div 1

    据说做TC题有助于提高知识水平? :) 传送门:https://284914869.github.io/AEoj/index.html 转载请注明链接:http://www.cnblogs.com/B ...

  3. Topcoder SRM 618 Div2 --900

    题意:给定两个NxN的棋盘,每个棋盘都有一个‘车’的摆放状态,问进行若干次交换,能否使棋盘1变为棋盘2. 交换规则:每次选两个‘车’,坐标分别为(r1,c1),(r2,c2),如果r1<r2并且 ...

  4. TopCoder SRM 559 Div 1 - Problem 900 CircusTents

    传送门:https://284914869.github.io/AEoj/559.html 题目简述: n个实心圆,两两没有交集,在第一个圆上找一个点,使得它到另外一个圆上某个点的最短距离的最小值尽量 ...

  5. TopCoder SRM 701 Div2 Problem 900 ThueMorseGame(博弈+预处理)

    题意  Alice和Bob在玩一个游戏,Alice先手. 每次一个人可以从一堆式子中拿走任意数量(不超过m)的式子. 取走最后一颗式子的人胜利. 当一个取完某一步的时候剩下的石子数量的二进制表示中1的 ...

  6. TopCoder[SRM587 DIV 1]:ThreeColorability(900)

    Problem Statement      There is a H times W rectangle divided into unit cells. The rows of cells are ...

  7. TopCoder入门

    TopCoder入门 http://acmicpc.info/archives/164?tdsourcetag=s_pctim_aiomsg 本文根据经典的TC教程完善和改编.TopCoder:htt ...

  8. ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 5166'

    凌晨收到同事电话,反馈应用程序访问Oracle数据库时报错,当时现场现象确认: 1. 应用程序访问不了数据库,使用SQL Developer测试发现访问不了数据库.报ORA-12570 TNS:pac ...

  9. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

随机推荐

  1. SQL Server 取日期时间部分

    在本文中,GetDate()获得的日期由两部分组成,分别是今天的日期和当时的时间: Select GetDate() 用DateName()就可以获得相应的年.月.日,然后再把它们连接起来就可以了: ...

  2. WWWFileSharePro 7.0 汉化破解绿色版,比hfs更稳定的Web文件共享服务器

    下载链接: http://pan.baidu.com/s/1eSykgFo 密码: m2s9 软件会被360杀毒软件误报病毒,楼主用火绒杀毒不误报. 本程序汉化由Bluefish完成,破解文件提取自网 ...

  3. HDU1760 A New Tetris Game NP态

    A New Tetris Game Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  4. PHP基础结业感想与总结!

    之前来传智是我认真调查和思考后得出的结论,我做程序员的第一目标是赚钱和学习技术,有一句话"艺多不压身".相信班上所有人的目标都是,这一点都不会庸俗,但是各个人的目的就未必一样了.我 ...

  5. GOLANG 常用命令

    golang常用命令: 命令 功能 build      编译包和依赖 run 编译并且直接运行 install 编译安装包和依赖 get 下载并安装包和依赖 fmt 调用gofmt格式化源码文件 d ...

  6. JS巧计__轮播

    横向轮播 function lxfScroll(main,titleli,alt,speed){ var lxfscroll = $(main); var ul = lxfscroll.find(&q ...

  7. golang os/exec 执行外部命令

    exec包执行外部命令,它将os.StartProcess进行包装使得它更容易映射到stdin和stdout,并且利用pipe连接i/o. func LookPath(file string) (st ...

  8. Opentaps安装小记

    这周了解了个MES项目需求,于是乎找了些开源项目了解下,有php+mysql写的weberp,配置起来相当方便,下一版webERP_v4.13,往F:\Apache\htdocs\一放,启动F:\Ap ...

  9. 前台jquery+ajax+json传值,后台处理完后返回json字符串,如何取里面的属性值?(不用springmvc注解)

    一.取属性值 前台页面: function select(id){ alert("hfdfhdfh"+id); $.ajax({ url:"selectByid.jsp& ...

  10. HTML 格式化等处理方法

    1.处理特殊字符串,清除空格,换行等 function DeleteHtml($str) { $str = trim ( $str ); // 清除字符串两边的空格 $str = preg_repla ...