码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-11-10 13:54:17      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:blog   io   color   ar   sp   for   on   2014   问题   

/*
2sat问题
输出任意一组可行解
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define N 2100
struct 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;}

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

标签:blog   io   color   ar   sp   for   on   2014   问题   

原文地址:http://blog.csdn.net/u011483306/article/details/40978907

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!