HDU-1151 Air Raid

给定一个有向无环图【DAG图】 求最小路径覆盖。。。

每个店出入分离成两个点,然后求二分图的最大匹配,最小路径覆盖=总点数-最大匹配数

#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <fstream>
#include <iostream>

#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define N 150

using namespace std;
int read()
{
	int x=0, f=1; char ch=getchar();
	while (ch<'0' || ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
	while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
	return x*f;
}

struct edge{int y, n;} e[N*N]; int fir[N], en;
int n, m, k[N*2], ans;
bool b[N*2];

void Add(int x, int y) { en++, e[en].y=y, e[en].n=fir[x], fir[x]=en; }

bool Find(int x)
{
	int o=fir[x], y=e[o].y;
	while (o)
	{
		if (!b[y])
		{
			b[y]=1; if (!k[y] || Find(k[y])) { k[y]=x; return true; }
		}
		o=e[o].n, y=e[o].y;
	}
	return false;
}

int main()
{
	int t=read(); while (t--)
	{
		n=read(); m=read();
		clr(fir, 0); clr(k, 0); en=0, ans=n;
		rep(i, 1, m) { int x=read(), y=read(); Add(x, y+N); }
		rep(i, 1, n) 
		{
			clr(b, 0); if (Find(i)) ans--;
		}
		printf("%d\n", ans);
	}
	return 0;
}

 

posted @ 2015-03-22 21:36  NanoApe  阅读(126)  评论(0编辑  收藏  举报
AmazingCounters.com