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;
    } 
  • 相关阅读:
    React源码解析-从头写一个React的难点与思路
    2017前端书籍推荐——如何一步步看懂框架源码
    React-ReactElement解析
    新手初学WPF本地化
    IOS 关闭键盘的几种方式
    专注技术
    test
    盒子模型
    CSS选择器详解(二)通用选择器和高级选择器
    CSS选择器详解(一)常用选择器
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7652072.html
Copyright © 2011-2022 走看看