POJ2594拐点弯的二分

  开始读题没理解题意,以为就是覆盖,可是怎么交都不对。。。 我就气愤了,结果去百度了一下发现奶奶的这题的机器人是可以隔点瞭望的,例如1->2->3、2->4、5->2  这个图  我现在5匹配2,2匹配4,那么1和3就剩下了,结果就是需要三个机器人。可是这与题意是相悖的,提议要求可一隔点向往,也就是说1能看到3,那么1和3也是可以匹配的,所以答案是2。(有向图的匹配和无向图的匹配是不一样的)

  那么接下来的任务就简单了,我把所有间接到达的点全部变成直接到达,让他自己去随便匹配好了,答案一定是对的。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<vector>
 5 #define maxn 510
 6 
 7 using namespace std;
 8 
 9 vector<int> g[maxn];
10 int group[maxn][maxn];
11 int link[maxn],vis[maxn];
12 int n,m;
13 
14 int dfs(int x)
15 {
16     for(int i=0;i<g[x].size();i++)
17     {
18         int e=g[x][i];
19         if(!vis[e])
20         {
21             vis[e]=1;
22             if(link[e]==-1||dfs(link[e]))
23             {
24                 link[e]=x;
25                 return true;
26             }
27         }
28     }
29     return false;
30 }
31 void floyd()
32 {
33       for(int i=1;i<=n;i++)
34       {
35           for(int j=1;j<=n;j++)
36           {
37              for(int k=1;k<=n;k++)
38              {
39                  if(group[k][i]&&group[i][j]&&j!=k) group[k][j]=1;
40              }
41           }
42       }
43 }
44 void setup_map()
45 {
46     for(int i=1;i<=n;i++)
47     {
48         for(int j=1;j<=n;j++)
49         {
50             if(group[i][j])
51                 g[i].push_back(j);
52         }
53     }
54 }
55 int main()
56 {
57     while(scanf("%d%d",&n,&m)!=EOF)
58     {
59         if(n==0&&m==0) break;
60         for(int i=1;i<=n;i++)
61             g[i].clear();
62         memset(group,0,sizeof(group));
63         for(int j=1;j<=m;j++)
64         {
65             int a,b;
66             scanf("%d%d",&a,&b);
67             group[a][b]=1;
68         }
69         floyd();
70         setup_map();
71         memset(link,-1,sizeof(link));
72         int sum=0;
73         for(int q=1;q<=n;q++)
74         {
75             memset(vis,0,sizeof(vis));
76             if(dfs(q)) sum++;
77         }
78         printf("%d\n",n-sum);
79     }
80     return 0;
81 }
View Code

 

你可能感兴趣的:(POJ2594拐点弯的二分)