zoukankan      html  css  js  c++  java
  • 洛谷 P3254 圆桌问题

    题目传送门

    源点到i单位的连容量为(r_i)的边,单位到每个餐桌连容量为1的边,餐桌j到汇点连容量为(c_j)的边,跑最大流

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    #define pd(i) (i % 2 == 1) ? i + 1 : i - 1
    
    using namespace std;
    
    int m,n,r,c,s,t,tot,dis[500],num,hu[500],ans;
    vector<int> d[500];
    struct kkk {
    	int fr,to,ll,rl;
    }e[200001];
    
    inline void add(int x,int y,int v) {
    	e[++tot].fr = x;
    	e[tot].to = y;
    	e[tot].rl = v;
    	e[tot].ll = 0;
    	d[x].push_back(tot);
    	e[++tot].fr = y;
    	e[tot].to = x;
    	e[tot].ll = 0;
    	e[tot].rl = 0;
    	d[y].push_back(tot);
    }
    
    inline bool bfs() {
    	memset(dis,-1,sizeof(dis));
    	queue<int> q;
    	q.push(s);
    	dis[s] = 0;
    	while(!q.empty()) {
    		int u = q.front();
    		q.pop();
    		for(int i = 0;i < d[u].size(); i++) {
    			kkk o = e[d[u][i]];
    			if(dis[o.to] == -1 && o.rl > o.ll) {
    				dis[o.to] = dis[u] + 1;
    				q.push(o.to);
    			}
    		}
    	}
    	return dis[t] != -1;
    }
    
    inline int dfs(int u,int a) {
    	if(u == t || a == 0) return a;
    	int sum = 0;
    	for(int &i = hu[u];i < d[u].size(); i++) {
    		kkk &o = e[d[u][i]];
    		if(dis[o.to] == dis[u] + 1) {
    			int f = dfs(o.to,min(a,o.rl - o.ll));
    			o.ll += f;
    			e[pd(d[u][i])].ll -= f;
    			a -= f;
    			sum += f;
    			if(a == 0) break;
    		}
    	}
    	return sum;
    }
    
    int main() {
    	scanf("%d%d",&m,&n);
    	t = m + 1 + n;
    	for(int i = 1;i <= m; i++) {
    		scanf("%d",&r);
    		num += r;
    		add(s,i,r);
    	}
    	for(int i = 1;i <= n; i++) {
    		scanf("%d",&c);
    		add(i + m,t,c);
    	}
    	for(int i = 1;i <= m; i++)
    		for(int j = 1;j <= n; j++)
    			add(i,j + m,1);
    	while(bfs()) {
    		memset(hu,0,sizeof(hu));
    		ans += dfs(s,10000000);
    	}
    	if(ans == num) printf("1
    ");
    	else {printf("0
    "); return 0;}
    	for(int i = 1;i <= m; i++) {
    		for(int j = 0;j < d[i].size(); j++)
    			if(e[d[i][j]].ll == 1 && e[d[i][j]].to != 0)
    				printf("%d ",e[d[i][j]].to - m);
    		printf("
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Spring Cloud学习笔记【二】Eureka 服务提供者/服务消费者(ribbon)
    Spring Cloud学习笔记【一】Eureka服务注册与发现
    Springboot分布式限流实践
    Springboot分布式锁实践(redis)
    Springboot2本地锁实践
    Springboot集成mybatis通用Mapper与分页插件PageHelper
    Springboot多数据源配置
    redis主从集群搭建
    assert的基本用法
    spring中BeanPostProcessor笔记
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/13658743.html
Copyright © 2011-2022 走看看