zoukankan      html  css  js  c++  java
  • hdu2853

                                  Assignment

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 659    Accepted Submission(s): 342


    Problem Description
    Last year a terrible earthquake attacked Sichuan province. About 300,000 PLA soldiers attended the rescue, also ALPCs. Our mission is to solve difficulty problems to optimization the assignment of troops. The assignment is measure by efficiency, which is an integer, and the larger the better.
    We have N companies of troops and M missions, M>=N. One company can get only one mission. One mission can be assigned to only one company. If company i takes mission j, we can get efficiency Eij. 
    We have a assignment plan already, and now we want to change some companies’ missions to make the total efficiency larger. And also we want to change as less companies as possible.
     
    Input
    For each test case, the first line contains two numbers N and M. N lines follow. Each contains M integers, representing Eij. The next line contains N integers. The first one represents the mission number that company 1 takes, and so on.
    1<=N<=M<=50, 1<Eij<=10000.
    Your program should process to the end of file.
     
    Output
    For each the case print two integers X and Y. X represents the number of companies whose mission had been changed. Y represents the maximum total efficiency can be increased after changing.
     
    Sample Input
    3 3
    2 1 3
    3 2 4
    1 26 2
    2 1 3
    2 3
    1 2 3
    1 2 3
    1 2
     
    Sample Output
    2 26
    1 2
    #include<iostream>
    using namespace std;
    const int inf = 1000000;
    const int maxn = 305;
    int vx[maxn],vy[maxn],g[maxn][maxn],weight[maxn],n,m,linky[maxn],lx[maxn],ly[maxn],ans;
    int dfs(int x)
    {
        int y;
        vx[x] = true;
        for(y=1;y<=m;y++)
        {
            if(!vy[y] && lx[x] + ly[y]==g[x][y])
            {
                vy[y] =true;
                if(linky[y]==-1 || dfs(linky[y]))
                {
                    linky[y] = x; return 1;
                }
            }
            else
            {
                if(weight[y] > lx[x]+ly[y] - g[x][y])
                {
                    weight[y] = lx[x] + ly[y] - g[x][y];
                }
            }
        }
        return 0;
    
    }
    int KM()
    {
        int i,j,lack,x;
        memset(linky,-1,sizeof(linky));
        memset(ly,0,sizeof(ly));
        for(i=1;i<=n;i++)
        {
            lx[i] = -inf;
            for(j=1;j<=m;j++)
            {
                if(g[i][j] > lx[i])
                    lx[i] = g[i][j];
            }
        }
        for(x=1;x<=n;x++)
        {
            for(j=1;j<=m;j++)
            {
                weight[j] = inf;
            }
            while(1)
            {
                memset(vx,0,sizeof(vx));
                memset(vy,0,sizeof(vy));
                if(dfs(x)) break;
                lack = inf;
                for(i=1;i<=n;i++)
                {
                    if(vx[i])
                    {
                        for(j=1;j<=m;j++)
                        {
                            if(!vy[j] && lack > lx[i] + ly[j] - g[i][j])
                            {
                                lack = lx[i] + ly[j] - g[i][j];
                            }
                        }
                    }
                }
                for(i=1;i<=n;i++)
                {
                    if(vx[i])
                        lx[i] -= lack;
                }
                for(j=1;j<=m;j++)
                {
                    if(vy[j])
                        ly[j] += lack;
                }
            }
        }
        ans = 0;
        for(i=1;i<=m;i++)
        {
            if(linky[i]!=-1)
            {
                ans += g[linky[i]][i];
            }
        }
        return ans;
    }
    int main()
    {
    //    int n,m;
        while(scanf("%d %d",&n,&m)!=EOF)
        {
            int i,j,tt,sum=0;
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=m;j++)
                {
                    scanf("%d",&g[i][j]);
                    g[i][j]*=100;
                }
            }
            for(i=1;i<=n;i++)
            {
                scanf("%d",&tt);
                g[i][tt]++;
                sum += g[i][tt];
            }
            KM();
             printf("%d %d
    ",sum%100-ans%100,ans/100-sum/100);  
        }
        return 0;
    }
  • 相关阅读:
    八进制转换成十进制(你会明白的,呵呵)
    从键盘读取7个数(150)的整数值,每读一个值打印出该值个数的*号.
    两个字符串的连接程序
    判断一个素数能被几个9整除.
    809*??=800*??+9*??+1 其中??代表的两位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果。
    一个偶数总能表示为两个素数的和.
    07所能组成的奇数的个数
    asp.net .ashx文件使用Server.MapPath解决方法
    MVC常见问题小总结
    amcharts_2.6.13左上角的广告咱去掉
  • 原文地址:https://www.cnblogs.com/Deng1185246160/p/3242349.html
Copyright © 2011-2022 走看看