Friendship
Time Limit: 2000MS   Memory Limit: 20000K
Total Submissions: 11429   Accepted: 3173

Description

In modern society, each person has his own friends. Since all the people are very busy, they communicate with each other only by phone. You can assume that people A can keep in touch with people B, only if 
1. A knows B's phone number, or 
2. A knows people C's phone number and C can keep in touch with B. 
It's assured that if people A knows people B's number, B will also know A's number.

Sometimes, someone may meet something bad which makes him lose touch with all the others. For example, he may lose his phone number book and change his phone number at the same time.

In this problem, you will know the relations between every two among N people. To make it easy, we number these N people by 1,2,...,N. Given two special people with the number S and T, when some people meet bad things, S may lose touch with T. Your job is to compute the minimal number of people that can make this situation happen. It is supposed that bad thing will never happen on S or T.

Input

The first line of the input contains three integers N (2<=N<=200), S and T ( 1 <= S, T <= N , and S is not equal to T).Each of the following N lines contains N integers. If i knows j's number, then the j-th number in the (i+1)-th line will be 1, otherwise the number will be 0.

You can assume that the number of 1s will not exceed 5000 in the input.

Output

If there is no way to make A lose touch with B, print "NO ANSWER!" in a single line. Otherwise, the first line contains a single number t, which is the minimal number you have got, and if t is not zero, the second line is needed, which contains t integers in ascending order that indicate the number of people who meet bad things. The integers are separated by a single space.

If there is more than one solution, we give every solution a score, and output the solution with the minimal score. We can compute the score of a solution in the following way: assume a solution is A1, A2, ..., At (1 <= A1 < A2 <...< At <=N ), the score will be (A1-1)*N^t+(A2-1)*N^(t-1)+...+(At-1)*N. The input will assure that there won't be two solutions with the minimal score.

Sample Input

  1. 3 1 3
  2. 1 1 0
  3. 1 1 1
  4. 0 1 1

Sample Output

  1. 1
  2. 2
    思路:
    感谢llw大佬的神奇优化!!!!
    耗时两天,终于AC了,总算是证明了自己的算法没有错误。
    网上遍地都是拆点的题解,奈何我实在是太弱了,弱到无法想象的地步,实在是看不懂拆点应该要怎么拆,所以我被逼无奈选择了暴力。
    那就是,限制一次dfs只能跑出容量为1的流,并将这条流上的所有点标记为不可用,直到一次Dinic结束。
    以此取代拆点的操作,是完全可行的,其他的操作都大体相同
    终于终于,体会到了AC的快乐,看着题解写出来的题,渐渐地成为了我自闭的根源
    代码
    邻接矩阵
  1. #include<iostream>
  2. #include<cstring>
  3. #include<queue>
  4. #include<cstdio>
  5. using namespace std;
  6. int mp[300][300];
  7. int n,s,t;
  8. const int inf = 2100000000;
  9. int vis[400],num[400];
  10. bool book[400];
  11.  
  12. struct edge
  13. {
  14. int u,v,next,w;
  15. }e[400010];
  16. int Head[400010],cur;
  17. int ans[400010];
  18.  
  19. void add(int x,int y)
  20. { e[cur].u=x;
  21. e[cur].v=y;
  22. e[cur].next=Head[x];
  23. e[cur].w=1;
  24. Head[x]=cur;
  25. cur++;
  26. e[cur].u=y;
  27. e[cur].v=x;
  28. e[cur].next=Head[y];
  29. e[cur].w=0;
  30. Head[y]=cur;
  31. cur++;
  32. }
  33.  
  34. bool bfs()
  35. {
  36. memset(vis,0,sizeof(vis));
  37. for(int i=1;i<=n;i++){
  38. num[i]=Head[i];
  39. }
  40. vis[s]=1;
  41. queue<int>q;
  42. q.push(s);
  43. int r=0;
  44. while(!q.empty()){
  45. int u=q.front();
  46. q.pop();
  47. int k=Head[u];
  48. while(k!=-1){
  49. if(!book[e[k].v]&&!vis[e[k].v]&&e[k].w){
  50. vis[e[k].v]=vis[u]+1;
  51. q.push(e[k].v);
  52. }
  53. k=e[k].next;
  54. }
  55. }
  56. return vis[t];
  57. }
  58.  
  59. int dfs(int u)
  60. {
  61. if(u==t){return 1;}
  62.  
  63. int &k=num[u];
  64. while(k!=-1){
  65. if(!book[e[k].v]&&vis[e[k].v]==vis[u]+1&&e[k].w){
  66. int d=dfs(e[k].v);
  67. e[k].w-=d;
  68. e[k^1].w+=d;
  69. if(d>0){book[u]=true;return 1;}
  70. }
  71. k=e[k].next;
  72. }
  73. return 0;
  74. }
  75.  
  76. void build()
  77. {
  78. cur=0;
  79. memset(Head,-1,sizeof(Head));
  80. for(int i=1;i<=n;i++){
  81. for(int j=1;j<=n;j++){
  82. if(mp[i][j]) add(i,j);
  83. }
  84. }
  85. }
  86.  
  87. int Dinic(int y)
  88. {
  89. memset(book,0,sizeof(book));
  90. book[y]=1;
  91. int ans=0;
  92. while(bfs()){
  93. int f;
  94. while((f=dfs(s))>0){//llw大佬太强了orz orz orz
  95. ans+=f;
  96. }
  97. }
  98. return ans;
  99. }
  100.  
  101. inline void rebuild(int tt)
  102. {
  103. for(int i=0;i<=cur;i+=2){
  104. if(e[i].v==tt||e[i].u==tt){e[i].w=e[i^1].w=0;}
  105. else if(e[i^1].w!=0){
  106. e[i].w=1;
  107. e[i^1].w=0;
  108. }
  109. }
  110.  
  111. }
  112. int main()
  113. {
  114. scanf("%d%d%d",&n,&s,&t);
  115. for(int i=1;i<=n;i++){
  116. for(int j=1;j<=n;j++){
  117. scanf("%d",&mp[i][j]);
  118. }
  119. }
  120. if(mp[s][t]==1){printf("NO ANSWER!\n");return 0;}
  121. build();
  122. int maxx=Dinic(0);
  123. rebuild(0);
  124. int num=0;
  125. for(int i=1;i<=n;i++){
  126. if(i==s||i==t){continue;}
  127. int y=Dinic(i);
  128. if(y<maxx){
  129. ans[++num]=i;
  130. maxx=y;
  131. if(maxx==0){break;}
  132. rebuild(i);
  133. }
  134. else rebuild(0);
  135. }
  136. if(num==0){printf("0\n");return 0;}
  137. printf("%d\n",num);
  138. for(int i=1;i<=num;i++){
  139. if(i!=1){printf(" ");}
  140. printf("%d",ans[i]);
  141. }
  142. printf("\n");
  143. }

  

  1.  

POJ 1815 Friendship (Dinic)的更多相关文章

  1. POJ 1815 Friendship (Dinic 最小割)

    Friendship Time Limit: 2000MS   Memory Limit: 20000K Total Submissions: 8025   Accepted: 2224 Descri ...

  2. POJ 1815 Friendship(字典序最小的最小割)

    Friendship Time Limit: 2000MS   Memory Limit: 20000K Total Submissions: 10744   Accepted: 2984 Descr ...

  3. POJ 1815 Friendship(最大流最小割の字典序割点集)

    Description In modern society, each person has his own friends. Since all the people are very busy, ...

  4. POJ - 1815 Friendship (最小点割集)

    (点击此处查看原题) 题目分析 题意:有n个人,编号记为1~n,n个人之间可能有人可以互相联系,如果A能和B联系,那么至少满足这两种情况之一:(1)A知道B的电话(2)A可以和C联系,并且C可以和B联 ...

  5. POJ 1815 Friendship(最小割+字典序输出割点)

    http://poj.org/problem?id=1815 题意: 在现代社会,每个人都有自己的朋友.由于每个人都很忙,他们只通过电话联系.你可以假定A可以和B保持联系,当且仅当:①A知道B的电话号 ...

  6. POJ 3281 Dining (网络流)

    POJ 3281 Dining (网络流) Description Cows are such finicky eaters. Each cow has a preference for certai ...

  7. POJ 2431 Expedition(探险)

    POJ 2431 Expedition(探险) Time Limit: 1000MS   Memory Limit: 65536K [Description] [题目描述] A group of co ...

  8. POJ 3414 Pots(罐子)

    POJ 3414 Pots(罐子) Time Limit: 1000MS    Memory Limit: 65536K Description - 题目描述 You are given two po ...

  9. POJ 1847 Tram (最短路径)

    POJ 1847 Tram (最短路径) Description Tram network in Zagreb consists of a number of intersections and ra ...

随机推荐

  1. vscode git設置

    1.git官网https://git-scm.com/download/win 链接下载:64-bit Git for Windows Setup,不要下载Portable,体积太大了: 如果git官 ...

  2. Spring Boot 构建电商基础秒杀项目 (十二) 总结 (完结)

    SpringBoot构建电商基础秒杀项目 学习笔记 系统架构 存在问题 如何发现容量问题 如何使得系统水平扩展 查询效率低下 活动开始前页面被疯狂刷新 库存行锁问题 下单操作步骤多,缓慢 浪涌流量如何 ...

  3. Java线程的创建方式三:Callable(四)

    一.Java实现多线程的三种方式 方式一:继承Thread类: public class Test extends Thread { public static void main(String[] ...

  4. ubuntu18.04系统下用devstack安装openstack(最新版)

    ubuntu18.04系统下用devstack安装openstack(最新版) 2018年12月14日 16:34:14 Cherls 阅读数:427   前期准备: 安装git,升级pip,其他 s ...

  5. java Builder模式创建不可变类

    package com.geostar.gfstack.operationcenter.logger.manager.common; /** * Created by Nihaorz on 2017/ ...

  6. Typecho——数据库无法连接问题

    报错 对不起,无法连接数据库,请先检查数据库配置再继续进行安装 解决方案 创建数据库 reate database databaseName; 远程权限 开启远程权限 GRANT ALL PRIVIL ...

  7. 微信小程序——部署云函数【三】

    部署login云函数 不部署的话,点击获取openid会报错,报错如下 解决方案呢,很明显的已经告诉我们了 搭建云环境 开通 同意协议 新建环境 每个小程序账号可以创建两个免费环境 确定 部署后再次请 ...

  8. 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)

    题目链接 POJ-3608 Bridge Across Islands 题意 依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离. 题解 旋转卡壳的应用之一:求两凸包的最近距离. 找到凸包 ...

  9. 动态逆序对[CDQ分治]

    题面 luogu cdq分治入门 注意删的是值不是位置! #include <cstdio> #include <algorithm> #include <cmath&g ...

  10. 利用SSH上传、下载(使用sz与rz命令)

    安装yum -y install lrzsz 用法sz用法:从服务器发送出去相当于下载一个文件sz filename 下载多个文件sz filename1 filename2rz用法:从外面接收回来, ...