hdu

http://acm.hdu.edu.cn/showproblem.php?pid=1150

有两种机器,A机器有n种模式,B机器有m种模式,现在有k个任务需要执行,没切换一个任务机器就需要重启一次,

如果任务i在机器A上执行,A机器需要一个对应的模式A,如果在机器B上执行,机器A需要一个模式B.

一直就是机器A在切换模式,现在让你安排一种合理的任务执行顺序,让机器重启次数最少.

每个任务之间连一条边.二分图的最小顶点覆盖就是求最少的点可以连接所有的边,然后转化成最大匹配即可.

这题就是初始状态是0,所以如果有一个任务的顶点为0,就不需要加入,因为不需要代价。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 using namespace std;
 5 const int maxn = 105;
 6 int n,m,k;
 7 vector<int>G[maxn];
 8 int link[maxn];
 9 bool vis[maxn];
10 
11 void add_edge(int u,int v)
12 {
13     G[u].push_back(v);
14     //G[v].push_back(u);
15 }
16 
17 bool dfs(int u)
18 {
19     for(int i=0;i<G[u].size();i++)
20     {
21         int v=G[u][i];
22         if(!vis[v])
23         {
24             vis[v]=true;
25             if(link[v]==-1||dfs(link[v]))
26             {
27                 link[v]=u;
28                 return true;
29             }
30         }
31     }
32     return false;
33 }
34 int main()
35 {
36     //freopen("a.txt","r",stdin);
37     int a,b,c;
38     while(~scanf("%d",&n)&&n)
39     {
40         scanf("%d%d",&m,&k);
41         for(int i=0;i<maxn;i++) G[i].clear();
42         for(int i=0;i<k;i++)
43         {
44             scanf("%d%d%d",&a,&b,&c);
45             if(b>0&&c>0)
46             add_edge(b,c);
47         }
48         int ans=0;
49         memset(link,-1,sizeof(link));
50         for(int i=0;i<n;i++)
51         {
52             memset(vis,0,sizeof(vis));
53             if(dfs(i)) ans++;
54         }
55         printf("%d
",ans);
56     }
57     return 0;
58 }
原文地址:https://www.cnblogs.com/nowandforever/p/4578929.html