HDU 4115 Eliminate the Conflict(2

题意:

思路:所以可以推出每轮必须出能平或赢的动作(两种选择)所以是2-sat。再找到约束关系即可

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int N = 20010;struct Edge{int v,next;}es[N*100];int val[N];int head[N];int n,m,cnt;inline void add_edge(int u,int v){es[cnt].v=v;es[cnt].next=head[u];head[u]=cnt++;}int tmp[N],sta[N],dfn[N],low[N],index,top;void tarjan(int u){tmp[u]=1;sta[++top]=u;dfn[u]=low[u]=++index;for(int i=head[u];~i;i=es[i].next){int v=es[i].v;if(tmp[v]==0) tarjan(v);if(tmp[v]==1) low[u]=min(low[u],low[v]);}if(dfn[u]==low[u]){do{int v=sta[top];low[v]=low[u];tmp[v]=2;}while(sta[top–]!=u);}}bool judge(){for(int i=0;i<2*n;i++){if(low[i]==low[i^1]) return false;}return true;}void ini(){memset(head,-1,sizeof(head));memset(tmp,0,sizeof(tmp));index=top=cnt=0;}int main(){int T;scanf("%d",&T);for(int cas=1;cas<=T;cas++){ini();scanf("%d%d",&n,&m);for(int i=0;i<n;i++){int c,u=i<<1;scanf("%d",&c);val[u]=c;val[u^1]=c%3+1;}for(int i=1;i<=m;i++){int u,v,op;scanf("%d%d%d",&u,&v,&op);u=(u-1)<<1,v=(v-1)<<1;if(op==0){if(val[u]==val[v]) add_edge(u,v);else if(val[u]==val[v^1]) add_edge(u,v^1);else add_edge(u,u^1);if(val[u^1]==val[v]) add_edge(u^1,v);else if(val[u^1]==val[v^1]) add_edge(u^1,v^1);else add_edge(u^1,u);if(val[v]==val[u]) add_edge(v,u);else if(val[v]==val[u^1]) add_edge(v,u^1);else add_edge(v,v^1);if(val[v^1]==val[u]) add_edge(v^1,u);else if(val[v^1]==val[u^1]) add_edge(v^1,u^1);else add_edge(v^1,v);}else{if(val[u]==val[v]) add_edge(u,v^1),add_edge(v,u^1);else if(val[u]==val[v^1]) add_edge(u,v),add_edge(v^1,u^1);if(val[u^1]==val[v]) add_edge(u^1,v^1),add_edge(v,u);else if(val[u^1]==val[v^1]) add_edge(u^1,v),add_edge(v^1,u);}}for(int i=0;i<2*n;i++) if(tmp[i]==0) tarjan(i);if(judge())printf("Case #%d: yes\n",cas);else printf("Case #%d: no\n",cas);}return 0;}

,美好的生命应该充满期待惊喜和感激

HDU 4115 Eliminate the Conflict(2

相关文章:

你感兴趣的文章:

标签云: