HDU 1150 浅谈二分图最小点覆盖水题

来源:互联网 发布:网络设备连接软件 编辑:程序博客网 时间:2024/06/07 12:52

这里写图片描述
世界真的很大
这道题基本上还是比较简单,怎么感觉最近老是在做水题。。
不要在意,即使是水题也有可以总结的地方
抱着这样的感觉来写博客。。
但是感觉字数什么的会很少吧。。

看题先:

description:

有两台机器A和B以及N个需要运行的任务。每台机器有M种不同的模式,而每个任务都恰好在一台机器上运行。如果它在机器A上运行,则机器A需要设置为模式ai,如果它在机器B上运行,则机器B需要设置为模式bi。每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。

input:

The input file for this program consists of several configurations. The first line of one configuration contains three positive integers: n, m (n, m < 100) and k (k < 1000). The following k lines give the constrains of the k jobs, each line is a triple: i, x, y.

The input will be terminated by a line containing a single zero.

output:

The output should be one integer per line, which means the minimal times of restarting machine.

唔。。
题目要求重启次数最少,即是说想要需要的模式总数最少。
就是说想要用最少的模式完成所有的任务
每个任务可以被A,B两台机器的两种模式分别完成
“最少的什么什么”“完成/覆盖什么什么”“两种”
关键字已经出来了,二分图的最小点覆盖

每个任务让A的模式对B的模式连边,这样就是一个二分图,求一个最大匹配即最小点覆盖就好

需要注意的是,我们求出的是最少的模式数,如果其中包含了0模式那么答案就要减1,因为一开始就是0模式,不需要额外重启

完整代码:

#include<stdio.h>#include<cstring>using namespace std;struct edge{    int v,last;}ed[400010];int n,m,K,num=0,ans=0,tot=0;int head[100010],book[100010],match[100010];void add(int u,int v){    num++;    ed[num].v=v;    ed[num].last=head[u];    head[u]=num;}int dfs(int u){    for(int i=head[u];i;i=ed[i].last)    {        int v=ed[i].v;        if(book[v]!=tot)        {            book[v]=tot;            if(!match[v] || dfs(match[v]))            {                match[u]=v,match[v]=u;                return 1;            }        }    }    return 0;}void init(){    memset(match,0,sizeof(match));    memset(head,0,sizeof(head));    memset(book,0,sizeof(book));    num=ans=tot=0;}int main(){    while(1)    {        init();        scanf("%d",&n);        if(!n) break ;        scanf("%d%d",&m,&K);        while(K--)        {            int x,u,v;            scanf("%d%d%d",&x,&u,&v);            add(u,v+n),add(v+n,u);        }        for(int i=0;i<n+m;i++)        {            tot++;            if(!match[i]) ans+=dfs(i);        }        if(match[0]) ans--;        if(match[n]) ans--;        if(match[0]==n) ans++;        printf("%d\n",ans);    }    return 0;}/*EL PSY CONGROO*/

嗯,就是这样

阅读全文
0 0
原创粉丝点击