zoukankan      html  css  js  c++  java
  • bzoj3693: 圆桌会议 二分图 hall定理


    目录

    题目链接

    bzoj3693: 圆桌会议

    题解

    对与每个人构建二分,问题化为时候有一个匹配取了所有的人

    Hall定理——对于任意的二分图G,G的两个部分为X={x1,x2,…,xn}和Y={y1,y2,…,ym},
    存在一个匹配M使得|M|=|X|的充要条件为对于X的任意一个子集A,与A相邻的点集记为T(A),一定有|T(A)|≥|A|

    拆环为链
    对于任意的区间[L,R],长度R-L+1,将所有区间[L,R]内的组插入操作求和为sum,如果sum > R - L + 1,显然不存在满足条件的匹配,否则一定存在解
    对于有意义的区间[L,R]一定在给出的操作区间上
    sum > R - L + 1 也就是 sum + P - 1 > Q
    前面那部分线段树维护
    对于每个右端点询问区间,每次把ai的值加到左端点上
    对于右端点扫过去就行了

    代码

    /*
    对与每个人构建二分,问题化为时候有一个匹配取了所有的人
    > Hall定理——对于任意的二分图G,G的两个部分为X={x1,x2,…,xn}和Y={y1,y2,…,ym},
    存在一个匹配M使得|M|=|X|的充要条件为对于X的任意一个子集A,与A相邻的点集记为T(A),一定有|T(A)|≥|A| 
    拆环为链
    对于任意的区间[L,R],长度R-L+1,将所有区间[L,R]内的组插入操作求和为sum,如果sum > R - L + 1,显然不存在满足条件的匹配,否则一定存在解 
    对于有意义的区间[L,R]一定在给出的操作区间上
    sum > R - L + 1 也就是 sum + P - 1 	> Q
    前面那部分线段树维护
    对于每个右端点询问区间,每次把ai的值加到左端点上 
    对于右端点扫过去就行了	
    */
    
    #include<map> 
    #include<vector> 
    #include<cstdio> 
    #include<algorithm> 
    #define gc getchar()
    #define pc putchar 
    #define LL long long
    inline int read() { 
    	int x = 0,f = 1; 
    	char c = gc; 
    	while(c < '0' || c > '9')c = gc; 
    	while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = gc; 
    	return x * f; 
    } 
    void print(int x) { 
    	if(x < 0) { 
    		pc('-'); 
    		x = -x; 
    	} 
    	if(x >= 10) print(x / 10); 
    	pc(x % 10 + '0'); 
    } 
    const int maxn = 1000007; 
    struct Q { 
    	int l,r,v; 
    	bool operator < (const Q & k)const { 
    		return r < k.r; 
    	} 
    } q[maxn]; 
    int d[maxn],cnt ,num; 
    int mx[maxn << 1],tag[maxn << 1]; 
    int n,m; 
    #define ls x << 1,l,mid
    #define rs x << 1 | 1,mid + 1,r 
    void update(int x) { 
    	mx[x] = std::max(mx[x << 1],mx[x << 1 | 1]); 
    } 
    void build(int x,int l,int r) { 
    	mx[x] = tag[x] = 0; 
    	if(l == r) { 
    		mx[x] = d[l] - 1; return; 
    	} 
    	int mid = l + r >> 1; 
    	build(ls); 
    	build(rs); 
    	update(x); 
    } 
    inline void pushdown(int x) { 
    	if(!tag[x]) return; 
    	tag[x << 1] += tag[x]; tag[x << 1 | 1] += tag[x]; 
    	mx[x << 1] += tag[x]; mx[x << 1 | 1] += tag[x]; 
    	tag[x] = 0; 
    } 
    
    void modify(int x,int l,int r,int L,int R,int val) { 
    	if(L <= l && R >= r) { 
    		tag[x] += val,mx[x] += val; 
    		return; 
    	} 
    	pushdown(x); 
    	int mid = l + r >> 1; 
    	if(L <= mid) modify(ls,L,R,val); 
    	if(R >  mid) modify(rs,L,R,val); 
    	update(x); 
    } 
    int query(int x,int l,int r,int L,int R) { 
    	if(l >= L && R >= r) return mx[x]; 
    	pushdown (x); 
    	int mid = l + r >> 1,ans = 0; 
    	if(L <= mid) ans = std::max(query(ls,L,R),ans); 
    	if(R >  mid) ans = std::max(query(rs,L,R),ans); 
    	return ans; 
    } 
    int main() { 
    	int T = read(); 
    	for(int t = 1;t <= T;t += 1) { 
    		cnt = num = 0; 
    		n = read(),m = read(); 
    		bool flag = false; 
    		LL sum = 0; 
    		for(int i = 1;i <= n;++ i) { 
    			q[i].l = read(),q[i].r = read(),q[i].v = read(); 
    			q[i].l ++;q[i].r ++;sum += q[i].v; 
    		} 
    		if(sum > m) { 
    			puts("No"); continue;
    		} 
    		cnt = n; 
    		for(int i = 1;i <= n;++ i)  
    			if(q[i].r < q[i].l) q[i].r += m; 
    			else { 
    				q[++cnt] = q[i]; 
    				q[cnt].l += m;q[cnt].r += m; 
    			} 
    		n = cnt; 
    		for(int i = 1;i <= n;++ i) d[++ num] = q[i].l,d[++ num] = q[i].r; 
    		std::sort(d + 1,d + num + 1); 
    		std::sort(q + 1,q + n + 1); 
    		build(1,1,n << 1); 
    		for(int i = 1;i <= n;++ i) 
    			q[i].l = std::lower_bound(d + 1,d + num + 1,q[i].l) - d, 
    			q[i].r = std::lower_bound(d + 1,d + num + 1,q[i].r) - d; 
    		for(int i = 1;i <= n;++ i) { 
    			modify(1,1,n << 1,1,q[i].l,q[i].v); 
    			//int k = query(1,1,n << 1,std::max(q[i].r - m + 1,1),q[i].r); 
    			//print(k); pc('
    '); 
    			if(query(1,1,n << 1,std::max(q[i].r - m + 1,1),q[i].r) > d[q[i].r]) { 
    				flag = true; 
    				break; 
    			} 
    		} 
    		puts(flag ? "No" : "Yes"); 
    	} 
    	return 0; 
    }  
    
  • 相关阅读:
    CentOS 6.3 安装 phpmyadmin
    mysql 常用命令
    用PHP将Unicode 转化为UTF-8
    Angularjs通过$http与服务器通信
    话说Angularjs的$resource模块
    AngularCSS--关于angularjs动态加载css文件的方法(仅供参考)
    Angular-ui-router + oclazyload + requirejs实现资源随route懒加载
    移动前端开发之viewport的深入理解
    AngularJS的ng-class切换class
    AngularJS中如何对Controller与Service进行分层设计与编码
  • 原文地址:https://www.cnblogs.com/sssy/p/9678682.html
Copyright © 2011-2022 走看看