hdu 3718

一个二分图最大匹配的题;

匈牙利算法不熟;

建了个模,用最小费用最大流解决了

  1 #include <iostream>
  2 #include <cstring>
  3 #define INF 9999999
  4 #include <cstdio>
  5 #include <queue>
  6 #include <vector>
  7 #include<algorithm>
  8 using namespace std;
  9 #define maxn 6100
 10 
 11 struct  edge
 12 {
 13     int from,to,cap,flow,cost;
 14 };
 15 struct MCMF
 16 {
 17     int n,m,s,t;
 18     vector<edge>edges;
 19     vector<int>G[maxn];
 20     int inq[maxn];
 21     int d[maxn];
 22     int p[maxn];
 23     int a[maxn];
 24     void init(int n)
 25     {
 26         this->n=n;
 27         for(int i=0; i<n; i++)
 28             G[i].clear();
 29         edges.clear();
 30     }
 31     void addedge(int from,int to,int cap,int cost)
 32     {
 33         edges.push_back((edge){from,to,cap,0,cost});
 34         edges.push_back((edge){to,from,0,0,-cost});
 35         m=edges.size();
 36         G[from].push_back(m-2);
 37         G[to].push_back(m-1);
 38     }
 39 
 40     bool bellman(int s,int t,int &flow,int &cost)
 41     {
 42         for(int i=0; i<n; i++)d[i]=INF;
 43         memset(inq,0,sizeof(inq));
 44         d[s]=0;
 45         inq[s]=1;
 46         p[s]=0;
 47         a[s]=INF;
 48 
 49         queue<int>Q;
 50         Q.push(s);
 51         while(!Q.empty())
 52         {
 53             int u = Q.front();
 54             Q.pop();
 55             inq[u] = 0;
 56             for(int i = 0; i < G[u].size(); i++)
 57             {
 58                 edge& e = edges[G[u][i]];
 59                 if(e.cap > e.flow && d[e.to] > d[u] + e.cost)
 60                 {
 61                     d[e.to] = d[u] + e.cost;
 62                     p[e.to] = G[u][i];
 63                     a[e.to] = min(a[u], e.cap - e.flow);
 64                     if(!inq[e.to])
 65                     {
 66                         Q.push(e.to);
 67                         inq[e.to] = 1;
 68                     }
 69                 }
 70             }
 71         }
 72         if(d[t] == INF) return false;
 73         flow += a[t];
 74         cost += d[t]*a[t];
 75         int u = t;
 76         while(u != s)
 77         {
 78             edges[p[u]].flow += a[t];
 79             edges[p[u]^1].flow -= a[t];
 80             u = edges[p[u]].from;
 81         }
 82         return true;
 83     }
 84     int Mincost(int s, int t)
 85     {
 86         int flow = 0, cost = 0;
 87         while(bellman(s, t, flow, cost));
 88         return cost;
 89     }
 90 };
 91 int n;
 92 int k,m;
 93 char s2[10200],s1[10200];
 94 int cur[30][30];
 95 int tot[30];
 96 void first_solve()
 97 {
 98     memset(cur,0,sizeof(cur));
 99     memset(tot,0,sizeof(tot));
100     for(int i=1; i<=n; i++)
101     {
102         int k1=s1[i]-'A'+1;
103         int k2=s2[i]-'A'+1;
104         tot[k1]++;
105         cur[k1][k2]++;
106     }
107 }
108 MCMF solve;
109 int main()
110 {
111     int t;
112     int st=0;
113     int final=201;
114     scanf("%d",&t);
115     while(t--)
116     {
117         scanf("%d%d%d",&n,&k,&m);
118         for(int i=1; i<=n; i++)
119         {
120             char s[5];
121             scanf("%s",s);
122             s1[i]=s[0];
123         }
124         for(int d=1; d<=m; d++)
125         {
126             solve.init(final+1);
127             for(int j=1; j<=n; j++)
128             {
129                 char s[5];
130                 scanf("%s",s);
131                 s2[j]=s[0];
132             }
133             first_solve();
134             for(int i=1; i<=26; i++)
135                 solve.addedge(st,i,1,0);
136             for(int i=1; i<=26; i++)
137             {
138                 for(int j=1; j<=26; j++)
139                 {
140                     int cnt=26+j;
141                     if (cur[i][j])
142                         solve.addedge(i,cnt,1,tot[i]-cur[i][j]);
143                     else solve.addedge(i,cnt,1,tot[i]);
144                 }
145             }
146             for(int i=1;i<=26;i++)solve.addedge(i+26,final,1,0);
147             int ans=n-solve.Mincost(st,final);
148             printf("%.4lf
",(double)ans/(double)n);
149         }
150     }
151     return 0;
152 }
View Code
原文地址:https://www.cnblogs.com/yours1103/p/3411417.html