HDU 1824 Let's go home
Chieh
posted @ 2015年1月04日 12:21
in HDUOJ
, 299 阅读
飞机票: http://acm.hdu.edu.cn/showproblem.php?pid=1824
其实这个题意好像有点模糊。。。比如第一个样例。。。如果0留下,那么1肯定要回家。。。则2肯定要留下。。。或则是1留下。。。那么2和0肯定要回家。。。或则是2留下,那么1肯定要回家,0肯定要留下。。。然而题意的意思是,0留下则1,2都的回家。或则1,2留下,0回家。。。而情况就只有 0,2回家,1留下,0,2留下,1回家, 跟题意不符。。。但是网上说是2-sat了。。那就2-sat吧。练练手。。。其实很简单。。。只要把两名队员看成一个正题就可以解决了
/* Author:Chieh Grow up happy */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map> #include <queue> #include <stack> #include <vector> #define LL long long using namespace std; const int maxn=2345; vector<int> V[maxn]; int can[maxn*2]; int n,m; void init() { for(int i=0; i<=2*n; i++)V[i].clear(); int o,p,q; for(int i=0; i<n; i++) { scanf("%d%d%d",&o,&p,&q); can[o]=i*2; can[p]=i*2+1; can[q]=i*2+1; } int u,v; for(int i=1; i<=m; i++) { scanf("%d%d",&u,&v); V[u].push_back(v^1); V[v].push_back(u^1); } } bool instack[maxn]; int dfn[maxn],low[maxn],sta[maxn],belong[maxn],indexx,scnt,cntnum; void tarjan(int u) { dfn[u]=low[u]=indexx++; instack[u]=1; sta[++scnt]=u; for(int i=0; i<V[u].size(); i++) { int v=V[u][i]; if(dfn[v]==-1) { tarjan(v); low[u]=min(low[u],low[v]); } else if(instack[v])low[u]=min(dfn[v],low[u]); } if(dfn[u]==low[u]) { for(int v=-1; v!=u; scnt--) { v=sta[scnt]; instack[v]=0; belong[v]=cntnum; } cntnum++; } } void play() { indexx=cntnum=0; scnt=-1; memset(dfn,-1,sizeof(dfn)); memset(instack,0,sizeof(instack)); for(int i=0; i<2*n; i++) { if(dfn[i]==-1)tarjan(i); } for(int i=0; i<n; i++) { if(belong[i*2]==belong[i*2+1]) { printf("no\n"); return; } } printf("yes\n"); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { init(); play(); } // cout << "Hello world!" << endl; return 0; }