poj 3683 2-sat问题,输出任意一组可行解

来源:互联网 发布:深圳php培训 编辑:程序博客网 时间:2024/05/03 00:22
/*2sat问题输出任意一组可行解*/#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#include<queue>#include<vector>using namespace std;#define N 2100struct node {int u,v,next;}ff[N],bian[N*N*8];int head[N],yong,low[N],dfn[N],belong[N],ans,top,index,stac[N],vis[N];void init(){    memset(head,-1,sizeof(head));    yong=index=ans=top=0;    memset(vis,0,sizeof(vis));    memset(dfn,0,sizeof(dfn));}void addedge(int u,int v){    bian[yong].u=u;//有的时候不能少,因为下面要用到    bian[yong].v=v;    bian[yong].next=head[u];    head[u]=yong++;}void tarjan(int u){    low[u]=dfn[u]=++index;    stac[++top]=u;    vis[u]=1;    int i;    for(i=head[u]; i!=-1; i=bian[i].next)    {        int v=bian[i].v;        if(!dfn[v])        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(vis[v])            low[u]=min(low[u],dfn[v]);    }    if(low[u]==dfn[u])    {        ans++;        int t;        do        {            t=stac[top--];            belong[t]=ans;            vis[t]=0;        }        while(t!=u);    }}int slove(int n){    int i;    for(i=0; i<n*2; i++)        if(!dfn[i])            tarjan(i);    // printf("%d\n",ans);    for(i=0; i<n; i++)        if(belong[i]==belong[i+n])            return 0;    return 1;}int judge(struct node a,struct node b) {if(a.v<=b.u||b.v<=a.u)    return 0;return 1;}int fp[N],indegree[N],color[N];vector<int>q[N];void print(struct node a) {  printf("%02d:%02d %02d:%02d\n",a.u/60,a.u%60,a.v/60,a.v%60);} void oper(int n) {  int i;  for(i=0;i<n;i++) {    fp[belong[i]]=belong[i+n];    fp[belong[i+n]]=belong[i];  }  for(i=1;i<=ans;i++) {    q[i].clear();    color[i]=0;    indegree[i]=0;  }  for(i=0;i<yong;i++) {    int aa=bian[i].u;    int bb=bian[i].v;    if(belong[aa]!=belong[bb]) {        q[belong[bb]].push_back(belong[aa]);        indegree[belong[aa]]++;    }  }  queue<int>qq;  for(i=1;i<=ans;i++) {    if(indegree[i]==0)        qq.push(i);  }  while(!qq.empty()) {    int cur=qq.front();    qq.pop();    if(color[cur]==0) {        color[cur]=1;        color[fp[cur]]=2;    }    for(i=0;i<(int)q[cur].size();i++) {     int v=q[cur][i];        if(--indegree[v]==0)        qq.push(v);    }  }  for(i=0;i<n;i++) {    if(color[belong[i]]==1)        print(ff[i]);    else        print(ff[i+n]);  } }int main() {     int n,i,j,k,u,v,uu,vv,d;     while(scanf("%d",&n)!=EOF) {        for(i=0;i<n;i++) {            scanf("%d:%d %d:%d%d",&u,&v,&uu,&vv,&d);            j=u*60+v;            k=uu*60+vv;            ff[i].u=j;ff[i].v=j+d;            ff[i+n].u=k-d;ff[i+n].v=k;        }        init();        for(i=0;i<n-1;i++)        for(j=i+1;j<n;j++) {            if(judge(ff[i],ff[j])) {                addedge(i,j+n);                addedge(j,i+n);            }            if(judge(ff[i],ff[j+n])) {                addedge(i,j);                addedge(j+n,i+n);            }            if(judge(ff[i+n],ff[j])) {                addedge(i+n,j+n);                addedge(j,i);            }            if(judge(ff[i+n],ff[j+n])) {                addedge(i+n,j);                addedge(j+n,i);            }        }        if(!slove(n))  {            printf("NO\n");            continue;        }            printf("YES\n");        oper(n);     }return 0;}

0 0