训练指南 UVALive - 3713 (2-SAT)
生活随笔
收集整理的這篇文章主要介紹了
训练指南 UVALive - 3713 (2-SAT)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
layout: post
title: 訓練指南 UVALive - 3713 (2-SAT)
author: "luowentaoaa"
catalog: true
mathjax: true
tags:
- 2-SAT
- 圖論
- 訓練指南
Astronauts
UVALive - 3713
題意
有A,B,C三個任務要分配個N個宇航員,每個宇航員恰好要分配一個任務,設平均年齡為X,只有年齡大于或等于X的宇航員才能分配任務A。只有年齡嚴格小于X的宇航員才能分配任務B。而任務C沒有限制。有M對宇航員相互討厭,因此不能分配到同一任務。編程找出一個滿足上述所有要求的任務分配方案。
題解
如果憎惡就代表不能一起去C,如果年齡相同就代表不能一起去A/B;
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=998244353; const int maxn=1e6+50; const ll inf=0x3f3f3f3f3f3f3f3fLL; struct TwoSAT{int n;vector<int> G[maxn*2];bool mark[maxn*2];int S[maxn*2],c;bool dfs(int x){if(mark[x^1])return false;if(mark[x])return true;mark[x]=true;S[c++]=x;for(int i=0;i<G[x].size();i++)if(!dfs(G[x][i]))return false;return true;}void init(int n){this->n=n;for(int i=0;i<n*2;i++)G[i].clear();memset(mark,0,sizeof(mark));}/// x=xval or y= yval;void add_caluse(int x,int xval,int y,int yval){x=x*2+xval;y=y*2+yval;G[x^1].push_back(y);///如果x為真 那么y必須為假;G[y^1].push_back(x);///如果y為真 那么x必須為假;}bool solve(){for(int i=0;i<n*2;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;} }; int n,a[maxn],m; TwoSAT solver; int tol; int is_young(int x){return a[x]*n<tol; } int main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);while(cin>>n>>m&&n&&m){tol=0;solver.init(n);for(int i=0;i<n;i++){cin>>a[i];tol+=a[i];}for(int i=0;i<m;i++){int a,b;cin>>a>>b;a--;b--;solver.add_caluse(a,1,b,1);if(is_young(a)==is_young(b))solver.add_caluse(a,0,b,0);}if(!solver.solve())cout<<"No solution."<<endl;else for(int i=0;i<n;i++)if(solver.mark[i*2])cout<<"C"<<endl;else if(is_young(i))cout<<"B"<<endl;else cout<<"A"<<endl;}return 0; }轉載于:https://www.cnblogs.com/luowentao/p/10343539.html
總結
以上是生活随笔為你收集整理的训练指南 UVALive - 3713 (2-SAT)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用runtime解决棘手问题锦集(持续
- 下一篇: 01 前端篇(标签)