poj 1422 Air Raid 最少路径覆盖
题目链接:http://poj.org/problem?id=1422
Consider a town where all the streets are one-way and each street leads from one intersection to another. It is also known that starting from an intersection and walking through town's streets you can never reach the same intersection i.e. the town's streets form no cycles.
With these assumptions your task is to write a program that finds the minimum number of paratroopers that can descend on the town and visit all the intersections of this town in such a way that more than one paratrooper visits no intersection. Each paratrooper lands at an intersection and can visit other intersections following the town streets. There are no restrictions about the starting intersection for each paratrooper.
题目描述:城镇里的街道从一个交叉口连接到另一个交叉口,街道都是单向的,并且从一个交叉口沿着街道出发不会回到相同的交叉口。伞兵降临在城镇的一个交叉口并可以沿着街道走向另一个没有被其他伞兵走过的交叉口,问城镇中的所有交叉口都被伞兵走过的情况下至少需要多少名伞兵。
算法分析:从题目中介绍城镇和街道的信息中可以知道是一个有向无环图,最少伞兵数量=DAG的最少路径覆盖(关于最少路径覆盖)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #define inf 0x7fffffff 8 using namespace std; 9 const int maxn=240+10; 10 11 int n,m; 12 int g[maxn][maxn],linker[maxn],vis[maxn]; 13 14 int dfs(int u) 15 { 16 for (int v=1 ;v<=n ;v++) if (g[u][v]) 17 { 18 if (!vis[v]) 19 { 20 vis[v]=1; 21 if (linker[v]==-1 || dfs(linker[v])) 22 { 23 linker[v]=u; 24 return 1; 25 } 26 } 27 } 28 return 0; 29 } 30 31 int hungary() 32 { 33 int ans=0; 34 for (int i=n+1 ;i<=2*n ;i++) 35 { 36 memset(vis,0,sizeof(vis)); 37 if (dfs(i)) ans++; 38 } 39 return ans; 40 } 41 42 int main() 43 { 44 int t; 45 scanf("%d",&t); 46 while (t--) 47 { 48 scanf("%d%d",&n,&m); 49 memset(g,0,sizeof(g)); 50 memset(linker,-1,sizeof(linker)); 51 int x,y; 52 for (int i=0 ;i<m ;i++) 53 { 54 scanf("%d%d",&x,&y); 55 x += n; 56 g[x][y]=1; 57 } 58 printf("%d\n",n-hungary()); 59 } 60 return 0; 61 }