zoukankan      html  css  js  c++  java
  • Priest John's Busiest Day

    POJ

    题意:有(n)对情侣结婚,第i对情侣的婚礼从(s_i)时刻开始,(t_i)时刻结束,并且需要(last_i)分钟完成一项仪式,仪式要么在婚礼刚开始进行,要么在婚礼结束前进行,即必须选择(s_i)$s_i+last_i$或者$t_i-last_i$(t_i)两个时间段之一.求(n)对情侣能否全部完成仪式,如果能,输出一种具体方案.(n<=1000.)

    在此之前,我们先来看一道名字一模一样,但有很大不同的题.洛咕

    题意:有一个司仪,要主持(n)场婚礼,给出婚礼的起始时间和终止时间,每个婚礼需要超过一半的时间进行仪式,并且仪式不能终止.问司仪能否主持(n)场婚礼.(n<=100000.)

    有没有发现两道题的不同:洛咕上这道题的仪式可以在任何时候开始,所以我们直接贪心来做就好了.把婚礼按照 开始时间+仪式持续时间 从小到大排序,然后从前往后扫,看每次婚礼能够在 结束时间之前 完成即可.注意一下:仪式持续时间=(婚礼开始时间+婚礼结束时间)/2+1,因为题目要求仪式超过婚礼一半时间,然后根据贪心,显然持续时间越短越好,所以就是这个式子.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=100005;
    struct ppx{int s,t,last;}a[N];
    inline bool cmp(ppx x,ppx y){return x.s+x.last<y.s+y.last;}
    inline bool check(int n){
    	int cnt=0;
        for(int i=1;i<=n;++i){
            cnt=max(cnt,a[i].s)+a[i].last;
            if(cnt>a[i].t)return false;
        }
        return true;
    }
    int main(){
    	while(1){
    		int n=read();if(!n)break;
    		for(int i=1;i<=n;++i){
    			a[i].s=read();a[i].t=read();
    			a[i].last=(a[i].t-a[i].s)/2+1;
    		}
    		sort(a+1,a+n+1,cmp);
    		if(check(n))puts("YES");
    		else puts("NO");
    	}
        return 0;
    }
    
    

    咳咳,回到本题.因为只有两种选择,所以考虑(2-SAT),每次枚举两个婚礼的仪式时间,如果有重叠就连边.建图后跑(Tarjan),然后检查是否有(i)(i+n)在同一个(SCC)里面即可.

    至于输出方案,蓝书上的拓扑排序法我打挂了,就写的是一种更简单但是很难想到的方法.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=2005;
    const int M=5e6+5;
    int s[N],t[N],last[N],belong[N],val[N],opp[N];
    int tot,head[N],nxt[M],to[M];
    int tim,top,num,dfn[N],low[N],st[N],color[N];
    inline bool pd(int l1,int r1,int l2,int r2){
    	if((l1>=l2&&l1<r2)||(r1>l2&&r1<=r2)||(l1<=l2&&r1>=r2))return 1;
    	return 0;
    }
    inline void add(int a,int b){
    	nxt[++tot]=head[a];head[a]=tot;to[tot]=b;
    }
    inline void tarjan(int u){
    	dfn[u]=low[u]=++tim;st[++top]=u;
    	for(int i=head[u];i;i=nxt[i]){
    		int v=to[i];
    		if(!dfn[v]){
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    		}
    		else if(!color[v])low[u]=min(low[u],dfn[v]);
    	}
    	if(dfn[u]==low[u]){
    		color[u]=++num;
    		belong[u]=num;
    		while(st[top]!=u){
    			color[st[top]]=num;
    			belong[st[top]]=num;
    			--top;
    		}
    		--top;
    	}
    }
    int main(){
    	int n=read();
    	for(int i=1;i<=n;++i){
    		int a=read(),b=read(),c=read(),d=read();
    		s[i]=a*60+b;t[i]=c*60+d;last[i]=read();
    	}
    	for(int i=1;i<n;++i)
    		for(int j=i+1;j<=n;++j){
    			if(pd(s[i],s[i]+last[i],s[j],s[j]+last[j]))
    				add(i,j+n),add(j,i+n);
    			if(pd(s[i],s[i]+last[i],t[j]-last[j],t[j]))
    				add(i,j),add(j+n,i+n);
    			if(pd(t[i]-last[i],t[i],s[j],s[j]+last[j]))
    				add(i+n,j+n),add(j,i);
    			if(pd(t[i]-last[i],t[i],t[j]-last[j],t[j]))
    				add(i+n,j),add(j+n,i);
    		}
    	for(int i=1;i<=2*n;++i)if(!dfn[i])tarjan(i);
    	for(int i=1;i<=n;++i){
    		if(belong[i]==belong[n+i]){puts("NO");return 0;}
    		opp[i]=n+i;opp[n+i]=i;
    	}
    	puts("YES");
    	for(int i=1;i<=n*2;++i)val[i]=belong[i]>belong[opp[i]];
    	for(int i=1;i<=n;++i){
    		if(!val[i])printf("%02d:%02d %02d:%02d
    ",s[i]/60,s[i]%60,(s[i]+last[i])/60,(s[i]+last[i])%60);
    		else printf("%02d:%02d %02d:%02d
    ",(t[i]-last[i])/60,(t[i]-last[i])%60,t[i]/60,t[i]%60);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    5-5图层的链接-新版本不常用
    5-4图层的不透明度
    5-3图层的层次关系
    5-2图层的选择
    5-1图层初识
    RTP协议文章收藏
    NW.js桌面应用开发(一)
    WebRTC笔记(一)
    mediasoup-demo解析-客户端
    npx工具
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11592826.html
Copyright © 2011-2022 走看看