zoukankan      html  css  js  c++  java
  • KM算法的应用

    HDU2255 模板     难度x

    HDU2282 思维     难度XXx

    HDU3722 模板     难度X

    HDU3395 模版   

    HDU1533 最小值模型 难度x

    HDU2853

    HDU3523

    HDU1533

    HDU3488

    HDU2448 +最短路

    HDU2255
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<memory.h>
    #include<algorithm>
    using namespace std;
    const int maxn=310;
    const int inf=0x7ffffff;
    int map[maxn][maxn];
    int vis1[maxn],vis2[maxn];
    int ex1[maxn],ex2[maxn];
    int lack[maxn];
    int link[maxn];
    int ans,n;
    bool _bfs(int v)
    {
        vis1[v]=true;
        for(int i=1;i<=n;i++){
            if(!vis2[i]){
                int tmp=ex1[v]+ex2[i]-map[v][i];
                if(tmp==0){
                  vis2[i]=true;
                  if(!link[i]||_bfs(link[i])){
                     link[i]=v;
                     return true;
                  }
                }
                else if(tmp<lack[i]) lack[i]=tmp;
            }
        }
        return false;
    }
    void _KM()
    {
        int t,i,j;
        memset(link,0,sizeof(link));
        memset(ex2,0,sizeof(ex2));
        for(i=1;i<=n;i++){
            ex1[i]=map[i][1];
            for(j=2;j<=n;j++)
             if(ex1[i]<map[i][j]) ex1[i]=map[i][j];
        }
        for(t=1;t<=n;t++){
            for(i=1;i<=n;i++) lack[i]=inf;//思考:为什么在这里? 
            while(true){ 
                memset(vis1,0,sizeof(vis1));
                memset(vis2,0,sizeof(vis2));
                if(_bfs(t))  break;
                int gap=inf;
                for(i=1;i<=n;i++)
                 if(!vis2[i]&&lack[i]<gap) gap=lack[i];
                for(i=1;i<=n;i++) if(vis1[i]) ex1[i]-=gap;
                for(i=1;i<=n;i++) if(vis2[i]) ex2[i]+=gap;
                for(i=1;i<=n;i++) if(!vis2[i])lack[i]-=gap;
            }
        }
        ans=0;
        for(i=1;i<=n;i++) ans+=map[link[i]][i];
        printf("%d
    ",ans);
    }
    int main()
    {
        int i,j;
        while(~scanf("%d",&n)){
            for(i=1;i<=n;i++)
             for(j=1;j<=n;j++) scanf("%d",&map[i][j]);
            _KM();
        }
        return 0;
    } 
    HDU1533
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<memory.h>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn=310;
    const int inf=0x7ffffff;
    int map[maxn][maxn];
    int vis1[maxn],vis2[maxn];
    int ex1[maxn],ex2[maxn];
    int lack[maxn];
    int link[maxn];
    int ans,n;
    int x1[maxn],x2[maxn],y[maxn],y2[maxn];
    int Abs(int v){
        if(v<0) v=-v;
        return v;
    }
    bool _bfs(int v)
    {
        vis1[v]=true;
        for(int i=1;i<=n;i++){
            if(!vis2[i]){
                int tmp=ex1[v]+ex2[i]-map[v][i];
                if(tmp==0){
                  vis2[i]=true;
                  if(!link[i]||_bfs(link[i])){
                     link[i]=v;
                     return true;
                  }
                }
                else if(tmp<lack[i]) lack[i]=tmp;
            }
        }
        return false;
    }
    void _KM()
    {
        int t,i,j;
        memset(link,0,sizeof(link));
        memset(ex2,0,sizeof(ex2));
        for(i=1;i<=n;i++){
            ex1[i]=map[i][1];
            for(j=2;j<=n;j++)
             if(ex1[i]<map[i][j]) ex1[i]=map[i][j];
        }
        for(t=1;t<=n;t++){
            for(i=1;i<=n;i++) lack[i]=inf;//思考:为什么在这里? 
            while(true){ 
                memset(vis1,0,sizeof(vis1));
                memset(vis2,0,sizeof(vis2));
                if(_bfs(t))  break;
                int gap=inf;
                for(i=1;i<=n;i++)
                 if(!vis2[i]&&lack[i]<gap) gap=lack[i];
                for(i=1;i<=n;i++) if(vis1[i]) ex1[i]-=gap;
                for(i=1;i<=n;i++) if(vis2[i]) ex2[i]+=gap;
                for(i=1;i<=n;i++) if(!vis2[i])lack[i]-=gap;
            }
        }
        ans=0;
        for(i=1;i<=n;i++)
           ans-=map[link[i]][i];
        ans=ans;
        printf("%d
    ",ans);
    }
    int main()
    {
        int i,j,m,cnt1,cnt2;
        char c;
        while(~scanf("%d%d",&n,&m)){
            if(n==0&&m==0) return 0;
            cnt1=cnt2=0;
            for(i=1;i<=n;i++)
             for(j=1;j<=m;j++) {
                    cin>>c;
                    if(c=='H') {
                        x1[++cnt1]=i;y[cnt1]=j;
                    }
                    if(c=='m'){
                        x2[++cnt2]=i;y2[cnt2]=j;
                    }
             }
             n=cnt1;
             for(i=1;i<=n;i++)
              for(j=1;j<=n;j++){
                    map[i][j]=-(Abs(x1[i]-x2[j])+Abs(y[i]-y2[j]));
              }
            _KM();
        }
        return 0;
    } 
    HDU2282
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<memory.h>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn=510;
    const int inf=0x7ffffff;
    int map[maxn][maxn];
    int vis1[maxn],vis2[maxn];
    int ex1[maxn],ex2[maxn];
    int lack[maxn];
    int link[maxn];
    int ans,n;
    int x[maxn],p[maxn],y[maxn],cnt1,cnt2;
    int Abs(int v){
        if(v<0) v=-v;
        return v;
    }
    bool _bfs(int v)
    {
        vis1[v]=true;
        for(int i=1;i<=cnt2;i++){
            if(!vis2[i]){
                int tmp=ex1[v]+ex2[i]-map[v][i];
                if(tmp==0){
                  vis2[i]=true;
                  if(!link[i]||_bfs(link[i])){
                     link[i]=v;
                     return true;
                  }
                }
                else if(tmp<lack[i]) lack[i]=tmp;
            }
        }
        return false;
    }
    void _KM()
    {
        int t,i,j;
        memset(link,0,sizeof(link));
        memset(ex2,0,sizeof(ex2));
        for(i=1;i<=cnt1;i++){
            ex1[i]=map[i][1];
            for(j=2;j<=cnt2;j++)
             if(ex1[i]<map[i][j]) ex1[i]=map[i][j];
        }
        for(t=1;t<=cnt1;t++){
            for(i=1;i<=cnt2;i++) lack[i]=inf;//思考:为什么在这里? 
            while(true){ 
                memset(vis1,0,sizeof(vis1));
                memset(vis2,0,sizeof(vis2));
                if(_bfs(t))  break;
                int gap=inf;
                for(i=1;i<=cnt2;i++)
                 if(!vis2[i]&&lack[i]<gap) gap=lack[i];
                for(i=1;i<=cnt1;i++) if(vis1[i]) ex1[i]-=gap;
                for(i=1;i<=cnt2;i++) if(vis2[i]) ex2[i]+=gap;
                for(i=1;i<=cnt2;i++) if(!vis2[i])lack[i]-=gap;
            }
        }
        ans=0;
        for(i=1;i<=cnt2;i++)
           ans-=map[link[i]][i];
        printf("%d
    ",ans);
    }
    int main()
    {
        int i,j,m;
        char c;
        while(~scanf("%d",&n)){
            memset(map,0,sizeof(map));
            cnt1=cnt2=0;
            for(i=1;i<=n;i++) scanf("%d",&p[i]);
            for(i=1;i<=n;i++){
               while(p[i]>1) {
                 x[++cnt1]=i;
                 p[i]--;
               }
               if(p[i]==0) y[++cnt2]=i;
            }
            for(i=1;i<=cnt1;i++)
             for(j=1;j<=cnt2;j++)
              map[i][j]=-min(Abs(x[i]-y[j]),n-Abs(x[i]-y[j]));
            _KM();
        }
        return 0;
    } 
    HDU3722
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<memory.h>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<string.h>
    using namespace std;
    const int maxn=310;
    const int inf=0x7ffffff;
    char c[310][1010];
    int map[maxn][maxn];
    int vis1[maxn],vis2[maxn];
    int ex1[maxn],ex2[maxn];
    int lack[maxn];
    int link[maxn];
    int ans,n;
    int x1[maxn],x2[maxn],y[maxn],y2[maxn];
    int _get(int u,int v){
        int i,j=0,L1=strlen(c[u]+1),L2=strlen(c[v]+1);
        for(i=L1;i>=1;i--){
            j++;
            if(j>L2||c[u][i]!=c[v][j]){
                j--;break;
            }
        }
        return j;
    }
    bool _bfs(int v)
    {
        vis1[v]=true;
        for(int i=1;i<=n;i++){
            if(!vis2[i]){
                int tmp=ex1[v]+ex2[i]-map[v][i];
                if(tmp==0){
                  vis2[i]=true;
                  if(!link[i]||_bfs(link[i])){
                     link[i]=v;
                     return true;
                  }
                }
                else if(tmp<lack[i]) lack[i]=tmp;
            }
        }
        return false;
    }
    void _KM()
    {
        int t,i,j;
        memset(link,0,sizeof(link));
        memset(ex2,0,sizeof(ex2));
        for(i=1;i<=n;i++){
            ex1[i]=map[i][1];
            for(j=2;j<=n;j++)
             if(ex1[i]<map[i][j]) ex1[i]=map[i][j];
        }
        for(t=1;t<=n;t++){
            for(i=1;i<=n;i++) lack[i]=inf;
            while(true){ 
                memset(vis1,0,sizeof(vis1));
                memset(vis2,0,sizeof(vis2));
                if(_bfs(t))  break;
                int gap=inf;
                for(i=1;i<=n;i++)
                 if(!vis2[i]&&lack[i]<gap) gap=lack[i];
                for(i=1;i<=n;i++) if(vis1[i]) ex1[i]-=gap;
                for(i=1;i<=n;i++) if(vis2[i]) ex2[i]+=gap;
                for(i=1;i<=n;i++) if(!vis2[i])lack[i]-=gap;
            }
        }
        ans=0;
        for(i=1;i<=n;i++)
           ans+=map[link[i]][i];
        ans=ans;
        printf("%d
    ",ans);
    }
    int main()
    {
        int i,j;
        while(~scanf("%d",&n)){
            for(i=1;i<=n;i++) scanf("%s",c[i]+1);
            for(i=1;i<=n;i++)
             for(j=1;j<=n;j++){
                 if(i==j) map[i][j]=0;
                 else     map[i][j]=_get(i,j); 
             }
            _KM();
        }
        return 0;
    } 
  • 相关阅读:
    1094. Car Pooling
    121. Best Time to Buy and Sell Stock
    58. Length of Last Word
    510. Inorder Successor in BST II
    198. House Robber
    57. Insert Interval
    15. 3Sum java solutions
    79. Word Search java solutions
    80. Remove Duplicates from Sorted Array II java solutions
    34. Search for a Range java solutions
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7652072.html
Copyright © 2011-2022 走看看