zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    C++函数参数传参的本质解析
    C#值类型和引用类型详解
    C#学习笔记(转换)
    C#学习笔记(泛型)
    # Java反射2——获取实体所有属性和方法,并对属性赋值
    Java反射1——扫描某个包下的所有类
    JSR教程2——Spring MVC数据校验与国际化
    JSR教程1——JSR 303
    Github如何撤销提交并清除痕迹
    论文第5章:Android绘图平台的实现
  • 原文地址:https://www.cnblogs.com/zhsl/p/2788229.html
Copyright © 2011-2022 走看看