POJ 3683 Priest John's Busiest Day
2-SAT简单题,判断一下两个开区间是否相交
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<stack> #include<algorithm> using namespace std; const int maxn=2000+10; int N,M; struct Time { int Start; int End; int cost; int S1,E1,S2,E2; } t[maxn]; char s[1000]; struct TwoSAT { int n; vector<int> G[maxn*2]; bool mark[maxn*2]; int S[maxn*2],c; bool dfs(int x) { if(mark[x^1]) return false; if(mark[x]) return true; mark[x]=true; S[c++]=x; for(int i=0;i<G[x].size();i++) if(!dfs(G[x][i])) return false; return true; } void init(int n) { this->n=n; for(int i=0;i<n*2;i++) G[i].clear(); memset(mark,0,sizeof mark); } void add_clause(int x,int y) { G[x].push_back(y^1); G[y].push_back(x^1); } bool solve() { for(int i=0;i<2*n;i+=2) if(!mark[i]&&!mark[i+1]) { c=0; if(!dfs(i)) { while(c>0) mark[S[--c]]=false; if(!dfs(i+1)) return false; } } return true; } }; bool F(int x1,int y1,int x2,int y2) { if(x1<x2&&x2<y1) return 1;//区间相交 if(x1<y2&&y2<y1) return 1;//区间相交 if(x2<x1&&x1<y2) return 1;//区间相交 if(x2<y1&&y1<y2) return 1;//区间相交 if(x1==x2||y1==y2) return 1;//区间相交 return 0;//区间不相交 } int main() { while(~scanf("%d",&N)) { TwoSAT T; T.n=N; T.init(N); for(int i=0; i<N; i++) { int h1,h2,m1,m2,tt; scanf("%s",s); h1=(s[0]-'0')*10+(s[1]-'0'); m1=(s[3]-'0')*10+(s[4]-'0'); scanf("%s",s); h2=(s[0]-'0')*10+(s[1]-'0'); m2=(s[3]-'0')*10+(s[4]-'0'); scanf("%d",&tt); t[i].Start=h1*60+m1; t[i].End=h2*60+m2; t[i].cost=tt; t[i].S1=t[i].Start; t[i].E1=t[i].Start+t[i].cost; t[i].S2=t[i].End-t[i].cost; t[i].E2=t[i].End; } for(int i=0;i<N;i++) { for(int j=i+1;j<N;j++) { if(F(t[i].S1,t[i].E1,t[j].S1,t[j].E1)) T.add_clause(2*i,2*j); if(F(t[i].S1,t[i].E1,t[j].S2,t[j].E2)) T.add_clause(2*i,2*j+1); if(F(t[i].S2,t[i].E2,t[j].S1,t[j].E1)) T.add_clause(2*i+1,2*j); if(F(t[i].S2,t[i].E2,t[j].S2,t[j].E2)) T.add_clause(2*i+1,2*j+1); } } if(T.solve()) { printf("YES\n"); for(int i=0;i<N;i++) { if(T.mark[2*i]) printf("%02d:%02d %02d:%02d\n",t[i].S1/60,t[i].S1%60,t[i].E1/60,t[i].E1%60); else printf("%02d:%02d %02d:%02d\n",t[i].S2/60,t[i].S2%60,t[i].E2/60,t[i].E2%60); } } else printf("NO\n"); } return 0; }