由于路径可以有重复的点,所以需要将间接相连的点连接
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 //顶点编号从0开始的 7 const int MAXN=510; 8 int uN,vN;//u,v数目 9 int g[MAXN][MAXN]; 10 int linker[MAXN]; 11 bool used[MAXN]; 12 bool dfs(int u)//从左边开始找增广路径 13 { 14 int v; 15 for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改 16 if(g[u][v]&&!used[v]) 17 { 18 used[v]=true; 19 if(linker[v]==-1||dfs(linker[v])) 20 {//找增广路,反向 21 linker[v]=u; 22 return true; 23 } 24 } 25 return false;//这个不要忘了,经常忘记这句 26 } 27 int hungary() 28 { 29 int res=0; 30 int u; 31 memset(linker,-1,sizeof(linker)); 32 for(u=0;u<uN;u++) 33 { 34 memset(used,0,sizeof(used)); 35 if(dfs(u)) res++; 36 } 37 return res; 38 } 39 void floyed(int n)//求传递闭包 40 { 41 for(int i=0;i<n;i++) 42 for(int j=0;j<n;j++) 43 { 44 if(g[i][j]==0) 45 { 46 for(int k=0;k<n;k++) 47 { 48 if(g[i][k]==1&&g[k][j]==1) 49 { 50 g[i][j]=1; 51 break; 52 } 53 } 54 } 55 } 56 } 57 int main() 58 { 59 int n,m; 60 int u,v; 61 while(scanf("%d%d",&n,&m)) 62 { 63 if(n==0&&m==0)break; 64 uN=vN=n; 65 memset(g,0,sizeof(g)); 66 while(m--) 67 { 68 scanf("%d%d",&u,&v); 69 u--;v--; 70 g[u][v]=1; 71 } 72 floyed(n); 73 printf("%d\n",n-hungary()); 74 } 75 return 0; 76 }
时间: 2024-09-28 20:11:40