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

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

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

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

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

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define INF 1e9
  4. #define N 5005
  5. #define id(i,j) ((i-1)*m+j)
  6. int n,m,TOT,S,T,P,head[N],d[N],a[N],p[N],cnt;
  7. bool vis[N];
  8. queue<int>q;
  9. char field[N][N];
  10. inline int read(){
  11. int x=,f=; char a=getchar();
  12. while(a<'' || a>'') {if(a=='-') f=-; a=getchar();}
  13. while(a>='' && a<='') x=x*+a-'',a=getchar();
  14. return x*f;
  15. }
  16. struct edges{
  17. int fr,to,cap,flow,cost,next;
  18. }e[*N];
  19.  
  20. inline void insert(int u,int v,int f,int c){
  21. e[cnt]=(edges){u,v,f,,c,head[u]};head[u]=cnt++;
  22. e[cnt]=(edges){v,u,,,-c,head[v]};head[v]=cnt++;
  23. }
  24. inline bool spfa(){
  25. memset(d,0x3f,sizeof(d));
  26. d[S]=; a[S]=INF; q.push(S);
  27. while(!q.empty()){
  28. int x=q.front(); q.pop(); vis[x]=;
  29. for(int i=head[x];i>=;i=e[i].next)
  30. if(d[e[i].to]>d[x]+e[i].cost && e[i].flow<e[i].cap){
  31. d[e[i].to]=d[x]+e[i].cost; p[e[i].to]=i;
  32. a[e[i].to]=min(a[x],e[i].cap-e[i].flow);
  33. if(!vis[e[i].to]) vis[e[i].to]=,q.push(e[i].to);
  34. }
  35. }
  36. return d[T]<INF;
  37. }
  38. inline int mincf(){
  39. int u=T;
  40. while(u!=S){
  41. e[p[u]].flow+=a[T];
  42. e[p[u]^].flow-=a[T];
  43. u=e[p[u]].fr;
  44. }
  45. TOT-=a[T];
  46. return a[T]*d[T];
  47. }
  48.  
  49. int main(){
  50. n=read(); m=read();
  51. for(int i=;i<=n;i++)
  52. scanf("%s",field[i]+);
  53. S=; T=*n*m+; P=n*m; TOT=;
  54. memset(head,-,sizeof(head));
  55. for(int i=;i<=n;i++)
  56. for(int j=;j<=m;j++){
  57. if(field[i][j]=='w') continue;
  58. if((i+j)%==){
  59. insert(S,id(i,j),,); TOT+=;
  60. if(field[i][j]!='C') insert(id(i,j),id(i,j)+*P,,),insert(id(i,j),id(i,j)+P,,);
  61. else {
  62. insert(id(i,j),id(i,j)+P,,); insert(id(i,j),id(i,j)+P,,);
  63. insert(id(i,j),id(i,j)+*P,,); insert(id(i,j),id(i,j)+*P,,);
  64. }
  65. if(j-> && field[i][j-]!='w') insert(id(i,j)+P,id(i,j-)+P,,);
  66. if(j+<=m && field[i][j+]!='w' ) insert(id(i,j)+P,id(i,j+)+P,,);
  67. if(i-> && field[i-][j]!='w') insert(id(i,j)+*P,id(i-,j)+*P,,);
  68. if(i+<=n && field[i+][j]!='w') insert(id(i,j)+*P,id(i+,j)+*P,,);
  69. }else{
  70. insert(id(i,j),T,,);
  71. if(field[i][j]!='C') insert(id(i,j)+*P,id(i,j),,),insert(id(i,j)+P,id(i,j),,);
  72. else{
  73. insert(id(i,j)+P,id(i,j),,); insert(id(i,j)+P,id(i,j),,);
  74. insert(id(i,j)+*P,id(i,j),,); insert(id(i,j)+*P,id(i,j),,);
  75. }
  76. }
  77. }
  78. int ans=;
  79. while(spfa()) ans+=mincf();
  80. if(TOT) ans=-;
  81. printf("%d\n",ans);
  82. }

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. HQL查询——HQL查询的基本用法

    HQL查询--HQL查询的基本用法 1.HQL语法类似于SQL语法,但是需要注意的是,HQL是一种完全面向对象的查询语言.SQL语言操作的对象是数据表.列等数据库对象,而HQL语言的操作对象是类.实例 ...

  2. smarty模板引擎

    1.    使用smarty 1.1 项目引入 // 3, 连接数据库,提取相关数据 $title = "Smarty模板引擎"; $content = "Smarty模 ...

  3. Virtualbox中不能为虚拟机打开一个新任务的原因及解决方法

    VirtualBox新建虚拟机时报错,不能为虚拟机打开一个新任务的原因 解决办法如下 1.保证bios里的virtualization technology的选项开启,不同电脑BIOS设置可能会不一样 ...

  4. 关于django访问默认后台admin的时候提示403错误,

    Forbidden (403) CSRF verification failed. Request aborted. You are seeing this message because this ...

  5. 【开园 and 计划】

    开园 啊啊啊啊啊啊啊啊,郁闷啊,头一回写博客,一刻钟前保存的草稿为何荡然无存??? 那少废话直击要点:今日乃我开园之日,开园为了改变.为了学习.为了积累. 计划 最长为时 3月,截止到 2016年9月 ...

  6. 如何实现修改FileUpload样式

    这里先隐藏FileUpload 然后用一个input button和一个text来模拟FileUpload 具体代码为 <asp:FileUpload ID="FileUpload1& ...

  7. PhpStorm配置svn时提示需要证书:authentication required的解决方法,总是弹出

    总是弹出下面的框框,每次输入svn账号密码,还是不行. 于是上网查了半天,需要安装和配置SlikSvn.于是就下载安装了. 完了还是不行,就尝试着配置. 上面和下面的加上,svn.exe的地址. 再次 ...

  8. mybatis mysql 调用视图

    java代码 @RequestMapping(value = "/testView", method = RequestMethod.GET) public @ResponseBo ...

  9. js_多个引号的用法

    str += "<input id='sel_DayB' width='120' onfocus=\"WdatePicker({skin:'whyGreen',dateFmt ...

  10. arm指令周期

    1.大部分算术运算和逻辑运算指令都是单周期的,例如加法.减法.位级运算和移位 2.乘法指令根据操作数位数的不同,从2-5个周期都有可能. 3.无条件跳转语句和跳转语句成功跳转,需要重新填充流水线,因此 ...