您的位置:首页 > 大数据 > 人工智能

LightOJ 1403 Air Raid 最小路径覆盖

2016-06-15 14:36 816 查看
题目:http://www.lightoj.com/volume_showproblem.php?problem=1403

题意:有一个小镇有十字路口和街道,抽象成n个顶点和m条有向边,两个顶点之间只有一条边且图中无环。现在有一些伞兵降落在小镇的任意路口,他们可以沿着街道走下去,求要参观所有的十字路口需要最少的伞兵数量

思路:最小路径覆盖裸题,直接建图,然后有最小路径覆盖 = 节点数 - 最大匹配

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

const int N = 1010;
struct edge
{
int to, next;
}g[N*N];
int head
, match
;
int nx, ny, cnt, cas = 0;
bool used
;
void add_edge(int v, int u)
{
g[cnt].to = u, g[cnt].next = head[v], head[v] = cnt++;
}
bool dfs(int v)
{
for(int i = head[v]; i != -1; i = g[i].next)
{
int u = g[i].to;
if(! used[u])
{
used[u] = true;
if(match[u] == -1 || dfs(match[u]))
{
match[u] = v;
return true;
}
}
}
return false;
}
int hungary()
{
int res = 0;
memset(match, -1, sizeof match);
for(int i = 1; i <= nx; i++)
{
memset(used, 0, sizeof used);
if(dfs(i)) res++;
}
return res;
}
int main()
{
int t, n, m, a, b;
scanf("%d", &t);
while(t--)
{
cnt = 0;
memset(head, -1, sizeof head);
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d", &a, &b);
add_edge(a, b);
}
nx = n, ny = m;
printf("Case %d: %d\n", ++cas, n - hungary());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: