POJ1325

Subject to the effect:

Two machines \ (A, B \) , respectively \ (n, m \) different modes, there are \ (K \) task, the \ (I \) task in \ (A \) needs mode \ (a_i \) , in \ (B \) required mode on \ (b_i \) , to complete a minimum of two machines many times mode conversion?

Greedy consider if we decide at some point the machine \ (A \) notes \ (a_i \) , then it must put all the \ (A \) required mode on \ (a_i \) tasks are to get rid of the most excellent

If we \ (A, B \) for each pattern as a node, connected to each task considered \ (a_i, b_i \) of one side, then any node may cover all edges connected thereto

Our task is to need all the edge nodes with minimal coverage

So is the bare minimum point bipartite graph cover

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace red{
#define int long long
#define eps (1e-8)
    inline int read()
    {
        int x=0;char ch,f=1;
        for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
        if(ch=='-') f=0,ch=getchar();
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    const int N=1e4+10;
    int n,m,k;
    struct node
    {
        int id,x,y;
    }d[N];
    int f[N],ret;
    bool vis[N];
    int head[N],cnt;
    struct point
    {
        int nxt,to;
        point(){}
        point(const int &nxt,const int &to):nxt(nxt),to(to){}
    }a[N<<2];
    inline void link(int x,int y)
    {
        a[++cnt]=point(head[x],y);head[x]=cnt;
        a[++cnt]=point(head[y],x);head[y]=cnt;
    }
    inline bool find(int x)
    {
        for(int i=head[x];i;i=a[i].nxt)
        {
            int t=a[i].to;
            if(vis[t]) continue;
            vis[t]=1;
            if(!f[t]||find(f[t]))
            {
                f[t]=x;
                return 1;
            }
        }
        return 0;
    }
    inline void main()
    {
        while("haku")
        {
            n=read();
            if(!n) break;
            m=read(),k=read();
            memset(head,0,sizeof(head));
            memset(f,0,sizeof(f));
            cnt=ret=0;
            for(int i=1;i<=k;++i)
            {
                d[i].id=read(),d[i].x=read(),d[i].y=read();
                if(!d[i].x||!d[i].y) continue;
                link(d[i].x,d[i].y+n);
            }
            for(int i=1;i<=n;++i)
            {
                memset(vis,0,sizeof(vis));
                if(find(i)) ++ret;
            }
            printf("%lld\n",ret);
        }
    }
}
signed main()
{
    red::main();
return 0;
}

Guess you like

Origin www.cnblogs.com/knife-rose/p/12085275.html