HDU2813 One fihgt one 最小权匹配

  题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2813

  典型的最小权覆盖,建图的时候用map标记就可以了,G++一般情况是可以900+ms过得,如果代码写得错了点,就会超时,C++叫一般快200ms的样子。比赛的时候,我加了优化,G++交了n次都超时,后来改成C++交就过了,郁闷得死!后来把map标记改为Trie树,结果203ms飘过,直接刷到了statistic的第三,所以说嘛,Trie的效率不是盖的,以后还是得多用Trie树取代map!

  其实还有很多优化的,比如用hash优化等等,不过这个效率也够了。

  map+KM:

 1 //STATUS:C++_AC_734MS_672KB
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<iostream>
 7 #include<string>
 8 #include<algorithm>
 9 #include<vector>
10 #include<queue>
11 #include<stack>
12 #include<map>
13 using namespace std;
14 #define LL long long
15 #define Max(a,b) ((a)>(b)?(a):(b))
16 #define Min(a,b) ((a)<(b)?(a):(b))
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define lson l,mid,rt<<1
19 #define rson mid+1,r,rt<<1|1
20 const int MAX=210,INF=0x7fffffff;
21 
22 map<string,int> ma1,ma2;
23 int w[MAX][MAX],lx[MAX],ly[MAX],S[MAX],T[MAX],y[MAX],g[MAX][MAX];
24 int n,m,k,slack;
25 
26 int dfs(int u)
27 {
28     S[u]=1;
29     int v,t;
30     for(v=1;v<=m;v++){
31         if(g[u][v]){
32             t=w[u][v]-lx[u]-ly[v];
33             if(!t){
34                 if(!T[v]){
35                     T[v]=1;
36                     if(!y[v] || dfs(y[v])){
37                         y[v]=u;
38                         return 1;
39                     }
40                 }
41             }
42             else if(t<slack)slack=t;
43         }
44     }
45     return 0;
46 }
47 
48 int KM()
49 {
50     int i,j,s;
51     mem(y,0);
52     mem(ly,0);
53     for(i=1;i<=n;i++){
54         lx[i]=INF;
55         for(j=1;j<=m;j++)
56             if(g[i][j] && w[i][j]<lx[i])lx[i]=w[i][j];
57     }
58     for(i=1;i<=n;i++){
59         while(1){
60             slack=INF;
61             mem(S,0);mem(T,0);
62             if(dfs(i))break;
63             for(j=1;j<=n;j++)if(S[j])lx[j]+=slack;
64             for(j=1;j<=m;j++)if(T[j])ly[j]-=slack;
65         }
66     }
67     for(s=0,i=1;i<=m;i++)
68         if(y[i])s+=w[y[i]][i];
69     return s;
70 }
71 
72 int main()
73 {
74  //   freopen("in.txt","r",stdin);
75     int i,j,t,cou1,cou2,a,b;
76     char s1[22],s2[22];
77     while(~scanf("%d%d%d",&n,&m,&k))
78     {
79         cou1=cou2=1;
80         mem(g,0);
81         ma1.clear(),ma2.clear();
82         for(i=0;i<k;i++){
83             scanf("%s%s%d",s1,s2,&t);
84             if(!ma1[s1])a=ma1[s1]=cou1++;
85             else a=ma1[s1];
86             if(!ma2[s2])b=ma2[s2]=cou2++;
87             else b=ma2[s2];
88             w[a][b]=t;
89             g[a][b]=1;
90         }
91 
92         printf("%d\n",KM());
93     }
94     return 0;
95 }

  Trie树+KM:

  1 //STATUS:G++_AC_208MS_18256KB
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 #include<math.h>
  6 #include<iostream>
  7 #include<string>
  8 #include<algorithm>
  9 #include<vector>
 10 #include<queue>
 11 #include<stack>
 12 #include<map>
 13 using namespace std;
 14 #define LL long long
 15 #define Max(a,b) ((a)>(b)?(a):(b))
 16 #define Min(a,b) ((a)<(b)?(a):(b))
 17 #define mem(a,b) memset(a,b,sizeof(a))
 18 #define lson l,mid,rt<<1
 19 #define rson mid+1,r,rt<<1|1
 20 const int MAX=210,INF=0x7fffffff;
 21 
 22 int w[MAX][MAX],lx[MAX],ly[MAX],S[MAX],T[MAX],y[MAX],g[MAX][MAX];
 23 int n,m,k,slack,cou1,cou2;
 24 struct Trie{
 25     Trie(){mem(p,0);val=-1;}
 26     Trie* p[55];
 27     int val;
 28 };
 29 
 30 int find(char *s,Trie *t,int& cou){
 31     int a;
 32     if(*s<='Z')a=*s-'A';
 33     else a=*s-'a'+26;
 34     if(*(s+1)=='\0'){
 35         if(!t->p[a]){
 36             t->p[a]=new Trie;
 37             return t->p[a]->val=cou++;
 38         }
 39         return t->p[a]->val;
 40     }
 41     if(!t->p[a]){
 42         t->p[a]=new Trie;
 43         return find(s+1,t->p[a],cou);
 44     }
 45     return find(s+1,t->p[a],cou);
 46 }
 47 
 48 int dfs(int u)
 49 {
 50     S[u]=1;
 51     int v,t;
 52     for(v=1;v<=m;v++){
 53         if(g[u][v]){
 54             t=w[u][v]-lx[u]-ly[v];
 55             if(!t){
 56                 if(!T[v]){
 57                     T[v]=1;
 58                     if(!y[v] || dfs(y[v])){
 59                         y[v]=u;
 60                         return 1;
 61                     }
 62                 }
 63             }
 64             else if(t<slack)slack=t;
 65         }
 66     }
 67     return 0;
 68 }
 69 
 70 int KM()
 71 {
 72     int i,j,s;
 73     mem(y,0);
 74     mem(ly,0);
 75     for(i=1;i<=n;i++){
 76         lx[i]=INF;
 77         for(j=1;j<=m;j++)
 78             if(g[i][j] && w[i][j]<lx[i])lx[i]=w[i][j];
 79     }
 80     for(i=1;i<=n;i++){
 81         while(1){
 82             slack=INF;
 83             mem(S,0);mem(T,0);
 84             if(dfs(i))break;
 85             for(j=1;j<=n;j++)if(S[j])lx[j]+=slack;
 86             for(j=1;j<=m;j++)if(T[j])ly[j]-=slack;
 87         }
 88     }
 89     for(s=0,i=1;i<=m;i++)
 90         if(y[i])s+=w[y[i]][i];
 91     return s;
 92 }
 93 int main()
 94 {
 95   //  freopen("in.txt","r",stdin);
 96     int i,j,t,a,b;
 97     char s1[22],s2[22];
 98     while(~scanf("%d%d%d",&n,&m,&k))
 99     {
100         Trie *Node=new Trie;
101         cou1=cou2=1;
102         mem(g,0);
103         for(i=0;i<k;i++){
104             scanf("%s%s%d",s1,s2,&t);
105             a=find(s1,Node,cou1);
106             b=find(s2,Node,cou2);
107             w[a][b]=t;
108             g[a][b]=1;
109         }
110 
111         printf("%d\n",KM());
112     }
113     return 0;
114 }
原文地址:https://www.cnblogs.com/zhsl/p/2788229.html