标签:div 后半程 next 不能 选择 || include name 新建
先象征性地描述一下问题:一组(或者一个)东西有且仅有两种选择,要么选这个,要么选那个,还有一堆的约束条件
图论问题,当然是建边跑图喽
给出模型:
模型一:两者(A,B)不能同时取
那么选择了A就只能选择B’,选择了B就只能选择A’
连边A→B’,B→A’
模型二:两者(A,B)不能同时不取
那么选择了A’就只能选择B,选择了B’就只能选择A
连边A’→B,B’→A
模型三:两者(A,B)要么都取,要么都不取
那么选择了A,就只能选择B,选择了B就只能选择A,选择了A’就只能选择B’,选择了B’就只能选择A’
连边A→B,B→A,A’→B’,B’→A’
模型四:两者(A,A’)必取A
那么,那么,该怎么说呢?先说连边吧。
连边A’→A
题目POJ3683
然后说一下这个题的意思:
如果某两个婚礼进行仪式的时间有重合
那么就存在了矛盾关系,通过这些关系连边
Tarjan缩点重新建图(这里建反向图),判断
将一个未着色点 x 上色同时,把与它矛盾的点 y 以及 y 的所有子孙节点上另外一种颜色
上色完成后,进行拓扑排序,选择一种颜色的点输出就是一组可行解
介绍一下实现:
int n,cnt,scc,ind,top; int a[maxn],b[maxn],belong[maxn],op[maxn]; bool inq[maxn];int dfn[maxn],low[maxn],q[maxn],col[maxn]; int g[maxn],gd[maxn],d[maxn]; struct Edge{int t,next;}e[maxm],ed[maxm];
ind是自增的用来记录dfn,scc是连通分量个数
belong用于存每一个点属于哪一个连通分量
然后op用来记录同一组的互斥条件
col用来存颜色
d用来存点的度数,便于拓扑排序
下面给出完整实现,感觉这个题可以很好地拆成几个很好地模板(就比如说拓扑排序,重新建图,强连通缩点,哈哈)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=2005; 6 const int maxm=2000005; 7 int n,cnt,scc,ind,top; 8 int a[maxn],b[maxn],belong[maxn],op[maxn]; 9 bool inq[maxn];int dfn[maxn],low[maxn],q[maxn],col[maxn]; 10 int g[maxn],gd[maxn],d[maxn]; 11 struct Edge{int t,next;}e[maxm],ed[maxm]; 12 void addedge(int u,int v) 13 { 14 e[++cnt].t=v;e[cnt].next=g[u]; 15 g[u]=cnt; 16 } 17 void addedge2(int u,int v) 18 { 19 d[v]++; 20 ed[++cnt].t=v;ed[cnt].next=gd[u]; 21 gd[u]=cnt; 22 } 23 inline int read() 24 { 25 int x=0,f=1;char ch=getchar(); 26 while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘)f=-1;ch=getchar();} 27 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 28 return x*f; 29 } 30 //a[2i]-b[2i]前半程 31 //a[2i-1]-b[2i-1]后半程 32 bool jud(int x,int y) 33 { 34 if(b[x]<=a[y]||a[x]>=b[y]) return 0; 35 return 1; 36 } 37 void build() 38 { 39 for(int i=1;i<=n;i++) 40 for(int j=i+1;j<=n;j++) 41 { 42 if(jud(2*i,2*j)) 43 { 44 addedge(2*i,2*j-1); 45 addedge(2*j,2*i-1); 46 } 47 if(jud(2*i,2*j-1)) 48 { 49 addedge(2*i,2*j); 50 addedge(2*j-1,2*i-1); 51 } 52 if(jud(2*i-1,2*j)) 53 { 54 addedge(2*i-1,2*j-1); 55 addedge(2*j,2*i); 56 } 57 if(jud(2*i-1,2*j-1)) 58 { 59 addedge(2*i-1,2*j); 60 addedge(2*j-1,2*i); 61 } 62 } 63 } 64 void tarjan(int x) 65 { 66 //cout<<x<<endl; 67 dfn[x]=low[x]=++ind; 68 q[++top]=x;inq[x]=1; 69 for(int tmp=g[x];tmp;tmp=e[tmp].next) 70 if(!dfn[e[tmp].t]) 71 { 72 tarjan(e[tmp].t); 73 low[x]=min(low[e[tmp].t],low[x]); 74 } 75 else if(inq[e[tmp].t]) 76 low[x]=min(dfn[e[tmp].t],low[x]); 77 if(low[x]==dfn[x]) 78 { 79 int temp=0;scc++; 80 while(temp!=x) 81 { 82 temp=q[top--]; 83 inq[temp]=0; 84 belong[temp]=scc; 85 } 86 } 87 } 88 void rebuild() 89 { 90 cnt=0; 91 for(int x=1;x<=2*n;x++) 92 for(int tmp=g[x];tmp;tmp=e[tmp].next) 93 if(belong[x]!=belong[e[tmp].t]) 94 { 95 //cout<<belong[e[tmp].t]<<" "<<belong[x]<<endl; 96 addedge2(belong[e[tmp].t],belong[x]); 97 } 98 99 } 100 void dfs(int x) 101 { 102 if(col[x]) return; 103 col[x]=-1; 104 for(int tmp=gd[x];tmp;tmp=ed[tmp].next) 105 dfs(ed[tmp].t); 106 } 107 void topsort() 108 { 109 for(int i=1;i<=scc;i++) 110 if(!d[i]) q[++top]=i; 111 while(top) 112 { 113 int temp=q[top--]; 114 //cout<<temp<<endl; 115 if(col[temp]) continue; 116 col[temp]=1;dfs(op[temp]); 117 for(int tmp=gd[temp];tmp;tmp=ed[tmp].next) 118 { 119 d[ed[tmp].t]--; 120 if(!d[ed[tmp].t]) q[++top]=ed[tmp].t; 121 } 122 } 123 } 124 void print(int x) 125 { 126 printf("%.2d:",x/60); 127 printf("%.2d ",x%60); 128 } 129 int main() 130 { 131 n=read(); 132 int x; 133 for(int i=1;i<=n;i++) 134 { 135 //a[2i]-b[2i]前半程 136 //a[2i-1]-b[2i-1]后半程 137 a[2*i]=read(); 138 a[2*i]=a[2*i]*60+read(); 139 b[2*i-1]=read(); 140 b[2*i-1]=b[2*i-1]*60+read(); 141 x=read(); 142 b[2*i]=a[2*i]+x; 143 a[2*i-1]=b[2*i-1]-x; 144 } 145 build(); 146 for(int i=1;i<=2*n;i++) 147 if(!dfn[i]) tarjan(i); 148 for(int i=1;i<=n;i++) 149 if(belong[2*i]==belong[2*i-1]) 150 {puts("NO");return 0;} 151 puts("YES"); 152 rebuild(); 153 for(int i=1;i<=n;i++) 154 { 155 op[belong[2*i]]=belong[2*i-1]; 156 op[belong[2*i-1]]=belong[2*i]; 157 } 158 topsort(); 159 for(int i=1;i<=n;i++) 160 if(col[belong[2*i]]==1) 161 print(a[2*i]),print(b[2*i]),puts(""); 162 else print(a[2*i-1]),print(b[2*i-1]),puts(""); 163 return 0; 164 }
标签:div 后半程 next 不能 选择 || include name 新建
原文地址:https://www.cnblogs.com/aininot260/p/9457908.html