zoukankan      html  css  js  c++  java
  • luoguP4313 文理分科

    luoguP4313 文理分科

    复习完之后做了道典型题目。

    这道题条件有点多

    我们逐个分析

    如果没有(sameart)或者(samescience)的限制,就是一个裸的最大权闭合子图的问题了

    但是再考虑有的话(其实还是一个最大权闭合子图)

    很明显我们还是可以按照套路分成两个集合.

    然后先按照权值分别划分(S),(T)集合

    然后再向他要求的学生连一条(infty)

    放一张奇丑无比的图

    AsZx0K.png

    感性理解一下就好了

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N = 2e5 + 3;
    const int M = 2e6 + 3;
    const int INF = 2e9; 
    int cur[N],head[N],high[N];
    struct edge{
    	int to;
    	int nxt;
    	int flow;	
    }e[M];
    int n,m,tot = 1,s,t;
    int ans = 0;
    int dx[5] = {0,1,-1,0,0},dy[5] = {0,0,0,1,-1};
    inline void add(int x,int y,int z){
    	e[++tot].to = y;
    	e[tot].flow = z;
    	e[tot].nxt = head[x];
    	head[x] = tot;
    	if(z < INF) ans += z;	
    }
    inline int read(){
    	int v = 0,c = 1;char ch = getchar();
    	while(!isdigit(ch)){
    		if(ch == '-') c = -1;
    		ch = getchar();	
    	}
    	while(isdigit(ch)){
    		v = v * 10 + ch - 48;
    		ch = getchar();	
    	}
    	return v * c;
    }
    inline bool bfs(){
    	queue <int> q;
    	for(int i = 0;i <= t;++i) high[i] = 0;
    	q.push(s);high[s] = 1;
    	while(!q.empty()){
    		int k = q.front();q.pop();
    		for(int i = head[k];i;i = e[i].nxt){
    			int y = e[i].to;
    			if(!high[y] && e[i].flow > 0)
    			q.push(y),high[y] = high[k] + 1;	
    		}
    	}
    	return high[t] != 0;
    }
    inline int dfs(int x,int dis){
    	if(x == t) return dis;
    	for(int &i = cur[x];i;i = e[i].nxt){
    		int y = e[i].to;
    		if(high[y] == high[x] + 1 && e[i].flow > 0){
    			int flow = dfs(y,min(dis,e[i].flow));
    			if(flow > 0){
    				e[i].flow -= flow;
    				e[i ^ 1].flow += flow;
    				return flow;	
    			}
    		}
    	}
    	return 0;
    }
    inline int dinic(){
    	int res = 0;
    	while(bfs()){
    		for(int i = 0;i <= t;++i) cur[i] = head[i];
    		while(int now = dfs(s,INF)) res += now;
    	}
    	return res;
    }
    int main(){
    	n = read(),m = read();
    	s = 3 * n * m + 1,t = s + 1;
    	for(int i = 0;i < n;++i)
    		for(int j = 0;j < m;++j){
    			int x = read();
    			add(s,i * m + j,x);
    			add(i * m + j,s,0);	
    		}
    	for(int i = 0;i < n;++i)
    		for(int j = 0;j < m;++j){
    			int x = read();
    			add(i * m + j,t,x);
    			add(t,i * m + j,0);	
    		}
    	for(int i = 0;i < n;++i)
    		for(int j = 0;j < m;++j){
    			int x = i * m + j + n * m,y = x + n * m;
    			for(int k = 0;k < 5;++k){
    				int xx = i + dx[k],yy = j + dy[k];
    				if(xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
    				add(x,xx * m + yy,INF);add(xx * m + yy,x,0);
    				add(xx * m + yy,y,INF);add(y,xx * m + yy,0);
    			//	add(x,xx * n + yy,0);add(xx * n + yy,x,INF);
    			//	add(xx * n + yy,y,0);add(y,xx * n + yy,INF);
    			}
    		}
    	for(int i = 0;i < n;++i)
    		for(int j = 0;j < m;++j){
    			int x = read();
    			add(s,i * m + j + n * m,x);
    			add(i * m + j + n * m,s,0);	
    		}
    	for(int i = 0;i < n;++i)
    		for(int j = 0;j < m;++j){
    			int x = read();
    			add(i * m + j + 2 * n * m,t,x);
    			add(t,i * m + j + 2 * n * m,0);	
    		}
    //	cout << ans << endl;
    	ans -= dinic();
    	printf("%d
    ",ans);
    	return 0;	
    }
    
  • 相关阅读:
    解决 JDK1.7 不支持 VCenter 6.7 的问题(涉及到Https TLS1.2协议)
    无法删除另一个分区的windows文件夹
    首次将项目从eclipse提交到服务器的SVN
    无法截图右键菜单
    配置文件无法修改(以修改my-default.ini为例)
    运行JavaWeb项目报错Access denied for user 'root'@'localhost' (using password: YES)
    jquery.page.js插件在使用时重复触发“上一页”和“下一页”操作
    请求ajax失败的原因(进入到error)
    ajax请求执行完成后再执行其他操作(jQuery.page.js插件使用为例)
    img标签src资源无法加载,报net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION错
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10635162.html
Copyright © 2011-2022 走看看