热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

POJ1815Friendship(最小点割集)

(点击此处查看原题)题目分析题意:有n个人,编号记为1~n,n个人之间可能有人可以互相联系,如果

(点击此处查看原题)

题目分析

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

因为某些人可能会丢失他的手机,导致他失去所有人的号码以及其他人手机中他的号码,也就是说这个人无法和任何人联系了;

此时给出两个人s,t,问至少有多少人失去他们的手机,可以使得这两个人s,t无法联系。

答案输出最少需要的人数以及失去手机的人的编号,如果存在多组解,输出字典序小的那一组。

 

思路:平时写的最小割问题是求边割集,这个题题目求的是最小点割集,对于这类题目我们采用如下建边方法:

1)将每个人代表的结点拆成两个结点,记编号1~n为入点,n+1~2*n为出点,由入点向出点建一条容量为1的边

2)对于可以联系的两人 a,b,由a的出点向b的入点建一条容量为inf的边,并由b的出点向a的入点建一条容量为inf的边

3)由于源点就是某个人,那么我们将这个人的出点当作源点

建好边之后,我们跑一遍最大流(最小割)就可以得到最小点割集

个人认为这个题主要麻烦在输出割点,我的方法是不断地的删点,如果删去这一点后得到的最大流大于删这点之前的最大流,那么这个点就是割点,为保证字典序最小,因而从1开始枚举割点

代码区

#include
#include

#include

#include

#include

#include
<string>
#include

#include

#include

#include

#include
#define bug cout <<"**********" <#define show(x, y) cout<<"["<#define LOCAL &#61; 1;
using namespace std;
typedef
long long ll;
const int inf &#61; 0x3f3f3f3f;
const ll mod &#61; 998244353;
const int Max &#61; 1e5 &#43; 10;
const int Max2 &#61; 1e3 &#43; 10;struct Edge
{
int to, flow, next;
} edge[Max
<<1];int n, s, t;
int head[Max2], tot;
int dis[Max2];
bool vis[210][210], cancel[210];
int id[Max2], cnt;void init()
{memset(head,
-1, sizeof(head));tot &#61; 0;
}
void add(int u, int v, int flow)
{edge[tot].to
&#61; v;edge[tot].flow &#61; flow;edge[tot].next &#61; head[u];head[u] &#61; tot&#43;&#43;;
}
void build()
{init();
for (int i &#61; 1; i <&#61; n; i&#43;&#43;){if (!cancel[i]){add(i, i &#43; n, 1);add(i &#43; n, i, 0);}}for (int i &#61; 1; i <&#61; n; i&#43;&#43;){for (int j &#61; 1; j <&#61; n; j&#43;&#43;){if(vis[i][j]){add(i &#43; n, j, inf);add(j, i &#43; n, 0);}}}
}
bool bfs()
{memset(dis,
-1, sizeof(dis));queue<int> q;q.push(s);dis[s] &#61; 0;while (!q.empty()){int u &#61; q.front();q.pop();for (int i &#61; head[u]; i !&#61; -1; i &#61; edge[i].next){int v &#61; edge[i].to;if (edge[i].flow > 0 && dis[v] &#61;&#61; -1){dis[v] &#61; dis[u] &#43; 1;if (v &#61;&#61; t)return true;q.push(v);}}}return false;
}
int dfs(int u, int flow_in)
{
if (u &#61;&#61; t)return flow_in;int flow_out &#61; 0;for (int i &#61; head[u]; i !&#61; -1; i &#61; edge[i].next){int v &#61; edge[i].to;if (edge[i].flow > 0 && dis[v] &#61;&#61; dis[u] &#43; 1){int flow &#61; dfs(v, min(flow_in, edge[i].flow));if (flow &#61;&#61; 0)continue;flow_in -&#61; flow;flow_out &#43;&#61; flow;edge[i].flow -&#61; flow;edge[i ^ 1].flow &#43;&#61; flow;if (flow_in &#61;&#61; 0)break;}}return flow_out;
}
int Dinic()
{
int sum &#61; 0;while (bfs()){sum &#43;&#61; dfs(s, inf);}return sum;
}
int main()
{
#ifdef LOCAL
//freopen("input.txt", "r", stdin);//freopen("output.txt", "w", stdout);
#endifwhile (scanf("%d%d%d", &n, &s, &t) !&#61; EOF){memset(cancel, 0, sizeof(cancel));memset(vis, 0, sizeof(vis));cnt &#61; 0;for (int i &#61; 1; i <&#61; n; i&#43;&#43;){for (int j &#61; 1,x; j <&#61; n; j&#43;&#43;){scanf("%d", &x);vis[i][j] &#61; x;}}if(vis[s][t]) //s,t可以直接联系&#xff0c;那就不存在最小割了
{printf("NO ANSWER!\n");continue;}s &#43;&#61; n;build();int min_cost &#61; Dinic();printf("%d\n", min_cost);if (min_cost &#61;&#61; 0)continue;int last &#61; min_cost;for (int i &#61; 1; i <&#61; n; i&#43;&#43;){if (i &#43; n &#61;&#61; s || i &#61;&#61; t)continue;cancel[i] &#61; true;build();int temp &#61; Dinic();if (temp //相比于不删除i点&#xff0c;删除i点之后最大流减少&#xff0c;则此点为割点
{id[&#43;&#43;cnt] &#61; i;last--;if (cnt &#61;&#61; min_cost)break;}else{cancel[i] &#61; false;}}for (int i &#61; 1; i )printf("%d ", id[i]);printf("%d\n", id[cnt]);}return 0;
}

View Code

转:https://www.cnblogs.com/winter-bamboo/p/11384939.html



推荐阅读
  • 线段树详解与实现
    本文详细介绍了线段树的基本概念及其在编程竞赛中的应用,并提供了一个具体的线段树实现代码示例。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • 本文深入探讨了Go语言中的接口型函数,通过实例分析其灵活性和强大功能,帮助开发者更好地理解和运用这一特性。 ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • spring boot使用jetty无法启动 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • importjava.io.*;importjava.util.*;publicclass五子棋游戏{staticintm1;staticintn1;staticfinalintS ... [详细]
  • 编译原理中的语法分析方法探讨
    本文探讨了在编译原理课程中遇到的复杂文法问题,特别是当使用SLR(1)文法时遇到的多重规约与移进冲突。文章讨论了可能的解决策略,包括递归下降解析、运算符优先级解析等,并提供了相关示例。 ... [详细]
  • 本文探讨了如何通过状态压缩动态规划(状压DP)和矩阵快速幂技术来解决公交线路问题。特别地,我们利用连续K个站点的状态来进行状态压缩,并通过矩阵快速幂加速计算过程。 ... [详细]
  • 本文探讨了在UIScrollView上嵌入Webview时遇到的一个常见问题:点击图片放大并返回后,Webview无法立即滑动。我们将分析问题原因,并提供有效的解决方案。 ... [详细]
  • 在Java开发中,保护代码安全是一个重要的课题。由于Java字节码容易被反编译,因此使用代码混淆工具如ProGuard变得尤为重要。本文将详细介绍如何使用ProGuard进行代码混淆,以及其基本原理和常见问题。 ... [详细]
  • 题目描述:计算从起点到终点的最小能量消耗。如果下一个单元格的风向与当前单元格相同,则消耗为0,否则为1。共有8个可能的方向。 ... [详细]
  • IO流——字符流 BufferedReader / BufferedWriter 进行文件读写
    目录节点流、处理流读文件:BufferedReader的使用写文件:BufferedWriter的使用节点流处理流节点流和处理流的区别和联系字符流Buf ... [详细]
  • 在构建 Caffe 时,可能会遇到与 Protobuf 版本不兼容导致的链接错误。本文将详细介绍这些错误及其解决方案。 ... [详细]
  • 本文探讨了如何在游戏启动画面中移除广告,特别是在游戏数据加载期间(大约5-6秒)广告会短暂显示的问题。通过调整XML布局和代码逻辑,可以实现广告的延迟加载或完全移除。 ... [详细]
author-avatar
手机用户2502930273
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有