poj3683
2-SAT算法流程
1.建立选择边
2.tarjan缩点(同一块内必然同时选择),判断是否存在可行解(若存在一对对立点{2*i,2*i-1}在同一块内,则不可行)
3.把缩点后的块之间建立反向选择边,并传递不选择命令(code中用op[ ]数组记录)
4.按照拓扑序找到一为选择的点(块),标为选择,传递不选择标记
//poj3683 #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> #define inf 2000000000 #define ll long long #define mod 1000000007 using namespace std; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,cnt,top,scc,ind; int a[2005],b[2005],belong[2005],op[2005]; int dfn[2005],low[2005],q[2005]; bool inq[2005]; struct edge{int to,next;}e[2000005],ed[2000005]; int last[2005],last2[2005],d[2005]; int color[2005]; bool jud(int x,int y){ if(b[x]<=a[y]||a[x]>=b[y])return 0; return 1; } void insert(int u,int v){e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;} void insert2(int u,int v){d[v]++;ed[++cnt].to=v;ed[cnt].next=last2[u];last2[u]=cnt;} void build(){ for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ if(jud(2*i,2*j)){insert(2*i,2*j-1);insert(2*j,2*i-1);} if(jud(2*i,2*j-1)){insert(2*i,2*j);insert(2*j-1,2*i-1);} if(jud(2*i-1,2*j)){insert(2*i-1,2*j-1);insert(2*j,2*i);} if(jud(2*i-1,2*j-1)){insert(2*i-1,2*j);insert(2*j-1,2*i);} } } void tarjan(int x){ dfn[x]=low[x]=++ind; q[++top]=x;inq[x]=1; for(int i=last[x];i;i=e[i].next) if(!dfn[e[i].to]){tarjan(e[i].to);low[x]=min(low[e[i].to],low[x]);} else if(inq[e[i].to])low[x]=min(dfn[e[i].to],low[x]); if(low[x]==dfn[x]){ int now=0;scc++; while(now!=x){ now=q[top--]; inq[now]=0; belong[now]=scc; } } } void rebuild(){ cnt=0; for(int x=1;x<=2*n;x++) for(int i=last[x];i;i=e[i].next) if(belong[x]!=belong[e[i].to]) insert2(belong[e[i].to],belong[x]); } void dfs(int x){ if(color[x])return; color[x]=-1; for(int i=last2[x];i;i=ed[i].next)dfs(ed[i].to); } void topsort(){ for(int i=1;i<=scc;i++)if(!d[i])q[++top]=i; while(top){ int now=q[top--]; if(color[now])continue; color[now]=1;dfs(op[now]); for(int i=last2[now];i;i=ed[i].next){ d[ed[i].to]--; if(!d[ed[i].to])q[++top]=ed[i].to; } } } void print(int x){printf("%.2d:",x/60);printf("%.2d ",x%60);} int main(){ n=read(); int x; for(int i=1;i<=n;i++){ a[2*i]=read();a[2*i]=a[2*i]*60+read(); b[2*i-1]=read();b[2*i-1]=b[2*i-1]*60+read(); x=read();b[2*i]=a[2*i]+x;a[2*i-1]=b[2*i-1]-x; } build(); for(int i=1;i<=2*n;i++)if(!dfn[i])tarjan(i); for(int i=1;i<=n;i++) if(belong[2*i]==belong[2*i-1]){puts("NO");return 0;} puts("YES"); rebuild(); for(int i=1;i<=n;i++){ op[belong[2*i]]=belong[2*i-1]; op[belong[2*i-1]]=belong[2*i]; } topsort(); for(int i=1;i<=n;i++) if(color[belong[2*i]]==1) print(a[2*i]),print(b[2*i]),puts(""); else print(a[2*i-1]),print(b[2*i-1]),puts(""); return 0; }