hdu 2426 Interesting Housing Problemの最も大きな権利はKMアルゴリズムにマッチします。
16198 ワード
テーマリンク:http://acm.hdu.edu.cn/showproblem.php?pid=2426
For any school,it is hard to find a feasible accomodation plan with everstudent asigned to a suitable apple appment while keeping everone happy,let alone an optimal one.Recently the president of University ABC,Peterson,Petersonウィhile Peterson dot like the delegating the tassk directly to the clasadvisorss s as as as mamamashshshshhos arararararararaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNevertheless、Peterson does not know how this task could be accocococococococompplished、so he asks you to solive this so-caled“interesting”problem for him.
Suppose that there re re N students and M rooms.Each student is asked to rate some rooms(not necessarly all M rooms)by stating how he/she likes the room.The rating can be represented astors the intement the stindersor negative implaying that the student does not like living in the room.Note that you can never assign a student to a room which he/she has not rated、as the absence of rating indicates the student the student cant.cant.cant.cant.cant.cant.cant.cant。
With limited information available,you've decided to simply find an assignment such that everent is assigned to a room he/she has rated,no two student s the same room,and the sum of rating Themizings。
学校にはn人の学生とm人のアパートの部屋がありますが、学生一人はいくつかの部屋に点数をつけています。点数が正しければ、学生はこの部屋が好きだと説明しています。0なら、この部屋に中立的で、負なら、この部屋が嫌いです。学生は好きではない部屋と採点のない部屋に住まないです。このn人の学生を手配して最大の点数を求めにきます。
アルゴリズム解析:KMアルゴリズム。n人の学生はX集として、m部屋をY集として、KMアルゴリズムを呼出してもいいです。
For any school,it is hard to find a feasible accomodation plan with everstudent asigned to a suitable apple appment while keeping everone happy,let alone an optimal one.Recently the president of University ABC,Peterson,Petersonウィhile Peterson dot like the delegating the tassk directly to the clasadvisorss s as as as mamamashshshshhos arararararararaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNevertheless、Peterson does not know how this task could be accocococococococompplished、so he asks you to solive this so-caled“interesting”problem for him.
Suppose that there re re N students and M rooms.Each student is asked to rate some rooms(not necessarly all M rooms)by stating how he/she likes the room.The rating can be represented astors the intement the stindersor negative implaying that the student does not like living in the room.Note that you can never assign a student to a room which he/she has not rated、as the absence of rating indicates the student the student cant.cant.cant.cant.cant.cant.cant.cant。
With limited information available,you've decided to simply find an assignment such that everent is assigned to a room he/she has rated,no two student s the same room,and the sum of rating Themizings。
学校にはn人の学生とm人のアパートの部屋がありますが、学生一人はいくつかの部屋に点数をつけています。点数が正しければ、学生はこの部屋が好きだと説明しています。0なら、この部屋に中立的で、負なら、この部屋が嫌いです。学生は好きではない部屋と採点のない部屋に住まないです。このn人の学生を手配して最大の点数を求めにきます。
アルゴリズム解析:KMアルゴリズム。n人の学生はX集として、m部屋をY集として、KMアルゴリズムを呼出してもいいです。
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=500+10;
10
11 int n,m;
12 int lx[maxn],ly[maxn],visx[maxn],visy[maxn];
13 int link[maxn],slack[maxn],w[maxn][maxn];
14
15 int dfs(int x)
16 {
17 visx[x]=1;
18 for (int y=1 ;y<=m ;y++) if (w[x][y]!=-1)
19 {
20 if (visy[y]) continue;
21 int t=lx[x]+ly[y]-w[x][y];
22 if (t==0)
23 {
24 visy[y]=1;
25 if (link[y]==-1 || dfs(link[y]))
26 {
27 link[y]=x;
28 return 1;
29 }
30 }
31 else if (slack[y]>t) slack[y]=t;
32 }
33 return 0;
34 }
35
36 int KM()
37 {
38 memset(link,-1,sizeof(link));
39 memset(ly,0,sizeof(ly));
40 for (int x=1 ;x<=n ;x++)
41 {
42 lx[x]=-inf;
43 for (int y=1 ;y<=m ;y++)
44 lx[x]=max(lx[x],w[x][y]);
45 }
46 for (int x=1 ;x<=n ;x++)
47 {
48 for (int i=1 ;i<=m ;i++) slack[i]=inf;
49 int flag=0;
50 for (int i=1 ;i<=m ;i++) if (w[x][i]!=-1) flag=1;
51 while (flag)
52 {
53 memset(visx,0,sizeof(visx));
54 memset(visy,0,sizeof(visy));
55 if (dfs(x)) break;
56 int d=inf;
57 for (int i=1 ;i<=m ;i++)
58 if (!visy[i] && d>slack[i]) d=slack[i];
59 for (int i=1 ;i<=n ;i++)
60 if (visx[i]) lx[i] -= d;
61 for (int i=1 ;i<=m ;i++)
62 {
63 if (visy[i]) ly[i] += d;
64 else slack[i] -= d;
65 }
66 }
67 }
68 int ans=0;
69 int vis[maxn];
70 memset(vis,0,sizeof(vis));
71 for (int i=1 ;i<=m ;i++)
72 {
73 if (link[i]!=-1)
74 {
75 ans += w[link[i] ][i];
76 vis[link[i] ]=1;
77 }
78 }
79 int i=1;
80 for (i=1 ;i<=n ;i++)
81 if (vis[i]==0) return -1;
82 return ans;
83 }
84
85 int main()
86 {
87 int e;
88 int ncase=1;
89 while (scanf("%d%d%d",&n,&m,&e)!=EOF)
90 {
91 memset(w,-1,sizeof(w));
92 int a,b,c;
93 for (int i=0 ;i<e ;i++)
94 {
95 scanf("%d%d%d",&a,&b,&c);
96 a++ ;b++ ;
97 if (c>=0) w[a][b]=c;
98 }
99 printf("Case %d: %d
",ncase++,KM());
100 }
101 return 0;
102 }