• UVa 1391


    题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=4137&mosmsg=Submission+received+with+ID+26582526

    如果两个互相讨厌的人年龄都是大于或小于 (x) 的,那么他们不能同时选同一种工作,如果年龄一个大于 (x),一个小于 (x),则保证都不选择任务 (C) 即可。因为每个人只能选两个任务,就转化成 (2-SAT) 问题

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 100010;
    
    int n, m;
    int age[maxn];
    
    vector<int> G[maxn*2];
    
    int S[maxn*2], c;
    bool mark[maxn*2];
    
    bool dfs(int u){
    	if(mark[u^1]) return false;
    	if(mark[u]) return true;
    	
    	mark[u] = true;
    	S[c++] = u;
    	for(int i = 0 ; i < G[u].size() ; ++i){
    		if(!dfs(G[u][i])) return false;
    	}
    	return true;
    }
    
    bool solve(){
    	memset(mark, 0, sizeof(mark));
    	memset(S, 0, sizeof(S));
    	c = 0;
    	for(int i = 0 ; i < 2 * n ; i += 2){
    		if(!mark[i] && !mark[i + 1]){
    			c = 0;
    			if(!dfs(i)){
    				while(c > 0) mark[S[--c]] = false;
    				if(!dfs(i + 1)) return false;
    			}
    		} 
    	}
    	return true;
    }
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	while(scanf("%d%d", &n, &m) == 2 && (n || m)){
    		for(int i = 0 ; i < 2*n ; ++i) G[i].clear(); 
    		double x = 0;
    		for(int i = 0 ; i < n ; ++i) {
    			scanf("%d", &age[i]);
    			x += age[i];
    		}
    		x = x / n;
    		
    		int u, v;
    		for(int i = 1 ; i <= m ; ++i){
    			scanf("%d%d", &u, &v);
    			--u, --v;
    			
    			if(age[u] >= x && age[v] >= x){
    				G[u*2].push_back(v*2+1);
    				G[v*2].push_back(u*2+1);
    				G[u*2+1].push_back(v*2);
    				G[v*2+1].push_back(u*2);
    			} else if(age[u] >= x && age[v] < x){
    				G[u*2+1].push_back(v*2);
    				G[v*2+1].push_back(u*2);
    			} else if(age[u] < x && age[v] >= x){
    				G[u*2+1].push_back(v*2);
    				G[v*2+1].push_back(u*2);
    			} else{
    				G[u*2].push_back(v*2+1);
    				G[v*2].push_back(u*2+1);
    				G[u*2+1].push_back(v*2);
    				G[v*2+1].push_back(u*2);
    			}
    		}
    		
    		if(solve()){
    			for(int i = 0 ; i < n ; ++i){
    				if(mark[i*2]){
    					printf("%c
    ", age[i] < x ? 'B' : 'A');
    				} else{
    					printf("%c
    ", 'C');
    				}
    			}
    		} else{
    			printf("No solution.
    ");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    洛谷P3620 [APIO/CTSC 2007] 数据备份
    洛谷P2744 量取牛奶
    洛谷P1560 蜗牛的旅行
    luogu P1776 宝物筛选_NOI导刊2010提高(02)
    luogu P1020 导弹拦截
    luogu P2015 二叉苹果树
    luogu P1137 旅行计划
    树形dp瞎讲+树形dp基础题题解
    luogu P1252 马拉松接力赛 P1803 凌乱的yyy / 线段覆盖
    luogu P1196 [NOI2002]银河英雄传说
  • 原文地址:https://www.cnblogs.com/tuchen/p/15025394.html
Copyright © 2020-2023  润新知