zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    最长回文字符(需要补)
    无重复字符的最长子串
    两数之和——链表
    两个数之和
    android 动画基础绘——帧动画(三)
    android 动画基础绘——view 动画(二)[补]
    android 动画基础绘——view 动画
    全国疫情精准定点动态更新(.net core)
    桶排序
    计数排序
  • 原文地址:https://www.cnblogs.com/yours1103/p/3411417.html
Copyright © 2011-2022 走看看