zoukankan      html  css  js  c++  java
  • [Luogu 1402] 酒店之王

    [Luogu 1402] 酒店之王

    <题目链接>


    这题其实匈牙利可以做来着,但是网络流感觉更直观吧。

    建模非常好想。

    // room 1..p
    // person1 p+1..p+n
    // person2 p+n+1..p+2n
    // dish p+2n+1..p+2n+q

    边权均为1。

    为什么拆人呢?因为人不能重复跑。

    就这样。好好写板子.jpg

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int MAXN=410,MAXM=20310,INF=0x3f3f3f3f;
    int n,p,q,S,T,cnt,ans,head[MAXN],cur[MAXN],dis[MAXN];
    struct edge
    {
    	int nxt,to,w;
    }e[MAXM];
    void AddEdge(int u,int v,int w)
    {
    	e[++cnt].nxt=head[u];
    	e[cnt].to=v;
    	e[cnt].w=w;
    	head[u]=cnt;
    }
    void AddEdges(int u,int v,int w)
    {
    	AddEdge(u,v,w);
    	AddEdge(v,u,0);
    }
    void Build(void)
    {
    	for(int i=1;i<=p;++i)
    		AddEdges(S,i,1);
    	for(int j=1;j<=n;++j)
    		for(int i=1,x;i<=p;++i)
    		{
    			scanf("%d",&x);
    			if(x)
    				AddEdges(i,p+j,1);
    		}
    	for(int i=1;i<=n;++i)
    		AddEdges(p+i,p+n+i,1);
    	for(int i=1;i<=n;++i)
    		for(int j=1,x;j<=q;++j)
    		{
    			scanf("%d",&x);
    			if(x)
    				AddEdges(p+n+i,p+(n<<1)+j,1);
    		}
    	for(int i=1;i<=q;++i)
    		AddEdges(p+(n<<1)+i,T,1);
    }
    bool BFS(void)
    {
    	queue<int> q;
    	memset(dis,0,sizeof dis);
    	q.push(S);
    	dis[S]=1;
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		for(int i=head[u],v;i;i=e[i].nxt)
    			if(e[i].w && !dis[v=e[i].to])
    			{
    				q.push(v);
    				dis[v]=dis[u]+1;
    			}
    	}
    	return dis[T];
    }
    int DFS(int u,int k)
    {
    	if(u==T || !k)
    		return k;
    	int sum=0;
    	for(int i=cur[u],v,f;i;i=e[i].nxt)
    		if(e[i].w && dis[v=e[i].to]==dis[u]+1 && (f=DFS(v,min(k,e[i].w))))
    		{
    			cur[u]=i;
    			e[i].w-=f,e[((i-1)^1)+1].w+=f;
    			k-=f,sum+=f;
    		}
    	if(!sum)
    		dis[u]=1;
    	return sum;
    }
    void Dinic(void)
    {
    	int f;
    	while(BFS())
    		while(memcpy(cur,head,sizeof head),f=DFS(S,INF))
    			ans+=f;
    	printf("%d
    ",ans);
    }
    int main(int argc,char *argv[])
    {
    	scanf("%d %d %d",&n,&p,&q);
    	T=p+(n<<1)+q+1;
    	Build();
    	Dinic();
    	return 0;
    }
    

    谢谢阅读。

  • 相关阅读:
    973. K Closest Points to Origin
    919. Complete Binary Tree Inserter
    993. Cousins in Binary Tree
    20. Valid Parentheses
    141. Linked List Cycle
    912. Sort an Array
    各种排序方法总结
    509. Fibonacci Number
    374. Guess Number Higher or Lower
    238. Product of Array Except Self java solutions
  • 原文地址:https://www.cnblogs.com/Capella/p/8287331.html
Copyright © 2011-2022 走看看