码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3343&HDU2413Against Mammoths (二分匹配)经典

时间:2014-08-18 22:09:03      阅读:437      评论:0      收藏:0      [点我收藏+]

标签:二分匹配

Against Mammoths

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


Problem Description
Back to year 3024, humans finally developed a new technology that enables them to conquer the alien races. The new technology made it possible to produce huge spaceships known as Saber Tooth spaceships as powerful as the aliens‘ defending mammoths. At that time, humans ruled several planets while some others were under control of the aliens. Using Saber Tooth ships, humans finally defeated aliens and this became the first Planet War in history. Our goal is to run a simulation of the ancient war to verify some historical hypotheses.

Producing each spaceship takes an amount of time which is constant for each planet but may vary among different planets. We call the number of spaceships each planet can produce in a year, the production rate of that planet. Note that each planet has a number of spaceships in it initially (before the simulation starts). The planets start producing ships when the simulation starts, so if a planet has nships initially, and has the production rate p, it will have n + p ships at the beginning of year 1, and n + i × p ships at the beginning of year i (years are started from zero).

Bradley Bennett, the commander in chief of the human armies, decided a strategy for the war. For each alien planet A, he chooses a corresponding human planet P, and produces spaceships in P until a certain moment at which he sends all spaceships in P to invade the planet A. No alien planet is invaded by two human planets and no human planet sends its spaceships to two different alien planets.

The defense power of the alien planets comes from their powerful mammoths. Each alien planet contains a number of mammoths initially and produces a number of mammoths each year (called the production rate of the planet). When a fight between spaceships and mammoths takes place, the side having the greater number of troops is the winner. If the spaceships win, the alien planet is defeated. In case the number of mammoths and spaceships are equal, the spaceships win.

The difficulty with planning this strategy is that it takes some time for the spaceships to reach the alien planets, and during this time, the aliens produce mammoths. The time required for spaceships to travel from each human planet to each alien planet is known. The ships can leave their planets only at the beginning of years (right after the ships are produced) and reach the alien planets at the beginning of years too (right after the mammoths are produced).

As an example, consider a human planet with two initial spaceships and production rate three invading an alien planet with two initial mammoths and production rate two. The time required to travel between the two planets is two years and the ships are ordered to leave at year one. In this case, five ships leave the human planet. When they reach the alien planet, they confront eight mammoths and will be defeated during the fight.

Bennett decided to prepare a plan that destroys every alien planet in the shortest possible time. Your task is to write a program to generate such a plan. The output is the shortest possible time (in years) in which every alien planet is defeated.

Input
There are multiple test cases in the input. The first line of each test case contains two numbers H and A which are the number of planets under the control of humans and aliens respectively (both between 1 and 250). The second line of the test case contains H non-negative integers n1 m1 n2 m2 … nH mH. The number ni is the initial number of Saber Tooth spaceships in the ith human planet and mi is the production rate of that planet. The third line contains A non-negative integers which specify the initial number of mammoths and the production rate of the alien planets in the same format as the second line. After the third line, there are H lines each containing A positive integers. The jth number on the ith line shows how many years it takes a spaceship to travel from the ith human planet to the jth alien planet. The last line of the input contains two zero numbers. Every number in the input except H and A is between 0 and 40000.

Output
The output for each test case contains a single integer which is the minimum time in which all alien planets can be defeated. If it is impossible to destroy all alien planets, the output should be IMPOSSIBLE.

Sample Input
2 1 2 3 0 3 2 2 2 2 0 0

Sample Output
6

Source
题意:人和外星人星球大战,人总共有H个星球,外星人有A个星球,现在人要用飞船去打外星人的飞船,要求每个人类星球只能对战一个外星球,且每个星球都开始有己知的飞船数,不论是人或外星人的星球,并每个星球都有一个生产飞般的生产率p,既每年可以生产p只飞般。人类飞般去打外星球时要经过一定的时间year才能到达所打的星球。而外星球也会在这一段时间里生产飞般,人类星球要想赢一个外星人的星球必须飞船数不小于外星球的飞船数。问人类星要想打赢所有的外星人星球最少需要多少年,如果不能打完所有外星球就输出IMPOSSIBLE.

解题:要赢首先得满足一定的条件:1. H>=A.  2.每个外星球必需有人类星球去打。3.一个人类星球只能对战一个外星球且这人类星球的飞船数在到达外个外星球时必须大于外个外星球的飞船数。每个外星球都在一对一的战争是败。
现在我们可以根据是一对一的关系可以想到二分匹配,那么怎么建边呢,通过预处理,把每个人类星球能用有限的年内打赢每个外星球可以建立起一个边,并记下每条边所用的时间。我们可以再分析一下,因为我们所求的是用最少年数打完所有外星球,那么可以先对所有的边按年数从小到大排序,再以外星球作为去匹配人类星球建边(好处:当一个外星球找不到一条增广路去配人类星球,那么我们发现外星球是不可能被打完),当外星球全部可以去匹配人类星球时,再从最大的一个接一个的边去除掉,如果去掉的不是匹配边则不用找增广路,再接着去掉一条大边,如果去掉的是匹配边,那么从这条边相关的外星球去找一条增广路,如果找不到则说明去掉的这条边就是我们要求的最少年数打完所有外星球。就可以直接得出答案。
PS:根据上面的250MS  AC。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
typedef struct nn
{
    __int64 s,p;
}planets;
typedef struct nnn
{
    __int64 hum,alien,fightyear;
}Fight;
__int64 HN,AN,fn;
Fight fight[260*260];
planets humans[260],aliens[260];
int set_fightyear()//计算每个人类星球所要的最少年数
{
    __int64 y,k,p,i,j,alie[260]={0},ak=0;
    fn=0;
    for( i=1;i<=HN;i++)
    scanf("%I64d%I64d",&humans[i].s,&humans[i].p);
    for(i=1;i<=AN;i++)
    scanf("%I64d%I64d",&aliens[i].s,&aliens[i].p);
    for( i=1;i<=HN;i++)
    for( j=1;j<=AN;j++)
    {
        scanf("%I64d",&y); 
        if(HN<AN)continue;//一定不能打完所有外星球
        k=aliens[j].s+y*aliens[j].p;
        k-=humans[i].s;
        fight[fn+1].hum=i; fight[fn+1].alien=j;
        if(k<=0)
        {
            fight[++fn].fightyear=y;
            if(alie[fight[fn].alien]==0)ak++,alie[fight[fn].alien]=1;
        }
        else
        {
            p=humans[i].p-aliens[j].p;
            if(p>0)
            {
                if(k%p==0)fight[++fn].fightyear=k/p+y;
                else fight[++fn].fightyear=k/p+1+y;
                if(alie[fight[fn].alien]==0)ak++,alie[fight[fn].alien]=1;
            }
        }
    }
    if(ak<AN)return 0;//存在外星球没有匹配的边
    else return 1;
}
__int64 map[260][260],mk[260],match[260],vist[260],hu,al;
__int64 find(int u)//二分匹配
{
    for(__int64 v=1;v<=mk[u];v++)
    if(!vist[map[u][v]])
    {
        vist[map[u][v]]=1;
        if(match[map[u][v]]==0||find(match[map[u][v]]))
        {
            match[map[u][v]]=u; return 1;
        }
    }
    return 0;
}
int cmp(Fight a,Fight b)//从小到大排序
{
    return a.fightyear<b.fightyear;
}
__int64 answear()
{
    __int64 i,j,ok=0,flag,alie;
    
    sort(fight+1,fight+1+fn,cmp);
    memset(mk,0,sizeof(mk));
    memset(match,0,sizeof(match));
    for( i=1;i<=fn;i++)//建图
    map[fight[i].alien][++mk[fight[i].alien]]=fight[i].hum;
    for(i=1;i<=AN;i++)//找增广路
    {
        for( j=1;j<=HN;j++)vist[j]=0;
        if(find(i)==0)return -1;//外星球没有匹配的边直接退出
    }
    for( i=fn;i>0;i--)
    {
        alie=fight[i].alien;
        mk[alie]--;//去掉大边
        if(match[map[alie][mk[alie]+1]]!=alie)continue;//不是匹配边
        match[map[alie][mk[alie]+1]]=0;
        for( j=1;j<=HN;j++)  vist[j]=0;
        flag=find(alie);
        if(flag==0)return fight[i].fightyear;//找不到增广路这条边就是答案
    }
}
int main()
{
    __int64 flag;
    while(scanf("%I64d%I64d",&HN,&AN)>0&&(HN||AN))
    {
        flag=-1;
        int f=set_fightyear();
        if(HN>=AN&&f)flag=answear();
        if(flag==-1)printf("IMPOSSIBLE\n");
        else printf("%I64d\n",flag);
    }
}


POJ3343&HDU2413Against Mammoths (二分匹配)经典,布布扣,bubuko.com

POJ3343&HDU2413Against Mammoths (二分匹配)经典

标签:二分匹配

原文地址:http://blog.csdn.net/u010372095/article/details/38665159

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!