本文共 3274 字,大约阅读时间需要 10 分钟。
Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploration? Have you ever explored treasure? If you never have such experiences, you would never know what fun treasure exploring brings to you.
Recently, a company named EUC (Exploring the Unknown Company) plan to explore an unknown place on Mars, which is considered full of treasure. For fast development of technology and bad environment for human beings, EUC sends some robots to explore the treasure. To make it easy, we use a graph, which is formed by N points (these N points are numbered from 1 to N), to represent the places to be explored. And some points are connected by one-way road, which means that, through the road, a robot can only move from one end to the other end, but cannot move back. For some unknown reasons, there is no circle in this graph. The robots can be sent to any point from Earth by rockets. After landing, the robot can visit some points through the roads, and it can choose some points, which are on its roads, to explore. You should notice that the roads of two different robots may contain some same point. For financial reason, EUC wants to use minimal number of robots to explore all the points on Mars. As an ICPCer, who has excellent programming skill, can your help EUC?Input
The input will consist of several test cases. For each test case, two integers N (1 <= N <= 500) and M (0 <= M <= 5000) are given in the first line, indicating the number of points and the number of one-way roads in the graph respectively. Each of the following M lines contains two different integers A and B, indicating there is a one-way from A to B (0 < A, B <= N). The input is terminated by a single line with two zeros.
Output
For each test of the input, print a line containing the least robots needed.
Sample Input
1 02 11 22 00 0
Sample Output
112
此题是最小边覆盖的变式,每个边可以经过多次,而最小边覆盖是每个边只能经过一次,看了别人的题解是用的Floyd缩点,其实就是将几个有公共顶点的顶点用一条边连接起来,比如1-2,2-3,就可以添加上一条边,1-3,这样的话用匈牙利算法就不会出现如果1要配对,但是2配对了,1就不能配对的情况,实际上就是添边来实现所谓的多次经过。
#include#include #include #include using namespace std;const int maxn=505;int n,m;int head[maxn];int vis[maxn];int match[maxn];int a[maxn][maxn];struct edge{ int to; int next;}edge[maxn*10];void Foyld (){ for (int k=1;k<=n;k++) { for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) { if(a[i][k]&&a[k][j]) { a[i][j]=1; } } } }}bool Find(int x){ for (int i=1;i<=n;i++) { if(!vis[i]&&a[x][i]) { vis[i]=1; if(match[i]==-1||Find(match[i])) { match[i]=x; return true; } } } return false;}int algor(){ memset (match,-1,sizeof(match)); int ans=0; for (int i=1;i<=n;i++) { memset (vis,0,sizeof(vis)); if(Find(i)) ans++; } return ans;}int main(){ while(scanf("%d%d",&n,&m)) { memset (a,0,sizeof(a)); if(n==0&&m==0) break; while(m--) { int x,y; scanf("%d%d",&x,&y); a[x][y]=1; } Foyld(); printf("%d\n",n-algor()); } return 0;}
转载地址:http://uzoen.baihongyu.com/