程序博客网 > 龙之信条美女捏脸数据
来源:互联网 发布:龙之信条美女捏脸数据 编辑:程序博客网 时间:2024/06/06 05:14
http://poj.org/problem?id=3683
/*题目描述:有n个婚礼,每个婚礼有起始时间si,结束时间ti,还有一个主持时间ti,ti必须安排在婚礼的开始或者结束,主持由祭祀来做,但是只有一个祭祀,所以各个婚礼的主持时间不能重复,问你有没有可能正常的安排主持时间,不能输出no,能的话要输出具体的答案:即每个婚礼的主持时间段是什么样的。*//*对于题意:主持时间要么在开始的时刻,要么在结束的时刻,而且各个婚礼之间有限制,因此用2-sat建图:对于婚礼i和婚礼j,i表示开始主持,i`表示结束主持,j也是一样枚举每一对不同的i和j,如果i和j冲突,连接ij`如果i和j`冲突,连接ij如果i`和j冲突,连接i`j`如果i`和j冲突,连接i`j*/#include<stdio.h>#include<string.h>#define MAXN 10000#define MAXM 1000000struct Edge//建图时用的{int from, to, next;}edge[MAXM];struct E{int from, to, next;}e[MAXM];struct Time{int from, to, len;}p[MAXN];int n, cnt, head[MAXN], head2[MAXN], cnt2;//建图时用到的变量int index, scc, dfn[MAXN], low[MAXN], belong[MAXN], num[MAXN];//tarjan算法用到的变量int out[MAXN], in[MAXN], top, stack[MAXN];bool instack[MAXN], ans[MAXN];char s1[9], s2[9];int opp[MAXN];void addedge(int u, int v)//建图{edge[cnt].from = u;edge[cnt].to = v;edge[cnt].next = head[u];head[u] = cnt++;}void addedge2(int u, int v){e[cnt2].from = u;e[cnt2].to = v;e[cnt2].next = head2[u];head2[u] = cnt2++;}int cal(char str[])//时间转换{int temp = 0;temp = str[0] - '0';temp *= 10;temp += str[1] - '0';temp *= 60;temp += ((str[3] - '0') * 10 + (str[4] - '0'));return temp;}bool judge(int f1, int l1, int f2, int l2)//判断是否冲突{if(f2 < f1 + l1 && f1 < f2 + l2)return true;return false;}int min(int a, int b){if(a<b)return a;elsereturn b;}void tarjan(int u)//强连通分支算法{int i, v;dfn[u] = low[u] = ++index;stack[++top] = u;instack[u] = true;for(i = head[u]; i!=-1; i = edge[i].next){v = edge[i].to;if(!dfn[v]){tarjan(v);low[u] = min(low[u], low[v]);}else if(instack[v]){low[u] = min(low[u], dfn[v]);}}if(dfn[u] == low[u]){scc++;//强连通分支数量while(1){v = stack[top--];instack[v] = false;belong[v] = scc;num[scc]++;if(u == v)break;}}}int q[MAXM], col[MAXN];bool solve(){int i;//int q[MAXM], col[MAXN];//tarjanindex = scc = top = 0;memset(instack, 0, sizeof(instack));memset(dfn, 0, sizeof(dfn));memset(num, 0, sizeof(num));for(i=0; i < 2*n; i++)if(!dfn[i])tarjan(i);for(i=0; i<n; i++){if(belong[i] == belong[i+n])return false;opp[belong[i]] = belong[i+n];opp[belong[i+n]] = belong[i];}//topsortcnt2 = 0;memset(in, 0, sizeof(in));memset(head2, -1, sizeof(head2));memset(col, 0, sizeof(col));for(i=0; i < cnt; i++)if(belong[edge[i].from] != belong[edge[i].to]){addedge2(belong[edge[i].to], belong[edge[i].from]);in[belong[edge[i].from]]++;}int l = 0, r = 0;for(i=0; i<scc; i++)if(in[i]==0)q[r++] = i;while(l<r){int u = q[l++];if(col[u] == 0){col[u] = 1;col[opp[u]] = -1;}int id = head2[u];while(id!=-1){if(--in[e[id].to] == 0)q[r++] = e[id].to;id = e[id].next;}}memset(ans, 0, sizeof(ans));for(i=0; i<n; i++)if(col[belong[i]] == 1)ans[i] = 1;return true;}void output(int t){printf("%02d:%02d", t/60, t%60);}int main(){//freopen("in.txt", "r", stdin);int i, j;while(scanf("%d", &n) != EOF){memset(head, -1, sizeof(head));cnt = 0;for(i=0; i<n; i++){int len;scanf("%s%s%d", s1, s2, &len);p[i].from = cal(s1);p[i].to = cal(s2);p[i].len = len;}for(i=0; i<n; i++){for(j=0; j<n; j++){if(i==j)continue;if(judge(p[i].from, p[i].len, p[j].from, p[j].len))addedge(i, j+n);if(judge(p[i].from, p[i].len, p[j].to - p[j].len, p[j].len))addedge(i, j);if(judge(p[i].to - p[i].len, p[i].len, p[j].from, p[j].len))addedge(i+n, j+n);if(judge(p[i].to - p[i].len, p[i].len, p[j].to - p[j].len, p[j].len))addedge(i+n, j);}}if(solve()){printf("YES/n");for(i=0; i<n; i++){if(ans[i]){output(p[i].from);printf(" ");output(p[i].from + p[i].len);printf("/n");}else{output(p[i].to - p[i].len);printf(" ");output(p[i].to);printf("/n");}}}elseprintf("NO/n");}return 0;}