2017 ACM 南宁现场赛 The Maximum Unreachable Node Set

题意:
给你n个点, m条边 , 然后让你集合A中的点集。(就是最多选多少边,使得集合内地点都不可达)
这道题emmm。。。现学现卖过的。。。。果然菜的无可救药。。。
这道题算法是 Flora + 二分图的最小顶点覆盖(二分图算法)
先用fiora求出可达矩阵(就是 如果 mpt[i][j] == mpt[j][k] 那么 mpt[i][k] 就是可以通达的)
然后我们可以通过这个图在找出它的最大匹配。
原贴参考链接:
链接1(匈牙利匹配算法)
链接二(题解)
在贴几个结论:


3个重要结论:

最大匹配数:最大匹配的匹配边的数目

最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择

最大独立集:选取最多的点,使任意所选两点均不相连

最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径。路径长可以为 0(即单个点)。

最小点覆盖数=最大匹配数

最小路径覆盖 =顶点数-最大匹配数

二分图最大独立集 = 顶点数 - 最大匹配数


注意:

在有向图中,一个点可以反复使用(有限制), 例如:
4个点 , 3 条边
1 3
2 3
3 4
他的最大匹配为二;
其匹配结果如下:
2 3 , 3 4 ;


最小路径覆盖问题理解

最小边覆盖问题理解


下面是代码:

#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std ;
const int maxn = 105 ;
int mpt[maxn][maxn] ;
int vis[maxn] ;
int link[maxn] ;
int n , m ;
#define INF 0x3f3f3f3f
void f(){

for(int k = 1 ; k <= n ; k++)
    for(int i = 1 ; i<= n ; i++)
    for(int j = 1 ; j <= n ; j++)
   if(mpt[i][k]&&mpt[k][j])
					mpt[i][j]=1;

}
int dfs(int num)
{
	for(int i=1;i<=n;i++)
    {
		if(mpt[num][i]&& !vis[i])
		{
			vis[i]=1;
			if(link[i]==-1||dfs(link[i]))
			{
				link[i] = num;
				return 1;
			}
		}
	}
	return 0;
}

int main(){
  int t ;
  cin >> t ;
  while(t--)
    {
        scanf("%d %d",&n,&m);
       int ans = 0 ;
         int u , v , w ;

        memset(mpt , 0 , sizeof(mpt)) ;

        memset(link , -1 , sizeof(link)) ;
        for(int i = 1 ; i <= m ; i++)
        { cin >> u >> w  ;
          mpt[u][w] = 1 ;
        }
        f();

		for(int i=1;i<=n;i++)
		{
		  memset(vis , 0 , sizeof(vis)) ;
			if(dfs(i))
			ans++;
		}
		printf("%d\n",n-ans);
    }
return 0 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值