国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[2-SAT][POJ2683][HDU1814]2-SAT兩種模板

2019-11-11 02:17:03
字體:
來源:轉載
供稿:網友
2-SAT有兩種模板,一種O(M)可以求任意可行解,另一種O(MN)十分暴力,所以可以求字典序最小或最大解

POJ2683

給定限制求任意可行解

這題就是O(M)的模板。

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <queue>#define N 4010#define mp(a,b) make_pair(a,b)using namespace std;typedef pair<int,int> PRs;typedef pair<prs,prs> prs4;prs4 p[N];int n,cnt,tp,ti,g;int G[N],sta[N],dfn[N],low[N],vis[N],bel[N],nG[N],v[N],d[N],opp[N];struct edge{ int t,nx;}E[N*N<<1];queue<int> Q;inline bool cover(prs a,prs b){ if(a.first>b.first) swap(a,b); return a.second>b.first;}inline void InserT(int x,int y){ E[++cnt].t=x;E[cnt].nx=G[y];G[y]=cnt;}inline void Insert(int x,int y){ E[++cnt].t=y;E[cnt].nx=nG[x];nG[x]=cnt;d[y]++;}void tarjan(int x){ vis[x]=1; dfn[x]=low[x]=++ti; sta[++tp]=x; for(int i=G[x];i;i=E[i].nx){ if(!vis[E[i].t]) tarjan(E[i].t); if(vis[E[i].t]==1) low[x]=min(low[x],low[E[i].t]); } if(low[x]==dfn[x]){ ++g; int k; do{ k=sta[tp--]; bel[k]=g; vis[k]=2; }while(tp&&k!=x); }}int main(){ freopen("t.in","r",stdin); freopen("t.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ int s,s1,t,t1,l; scanf("%d:%d %d:%d %d",&s,&s1,&t,&t1,&l); s=s*60+s1; t=t*60+t1; p[i]=mp(mp(s,s+l),mp(t-l,t)); } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ if(cover(p[i].first,p[j].first)) InserT(i<<1,j<<1|1),InserT(j<<1,i<<1|1); if(cover(p[i].first,p[j].second)) InserT(i<<1,j<<1),InserT(j<<1|1,i<<1|1); if(cover(p[i].second,p[j].first)) InserT(i<<1|1,j<<1|1),InserT(j<<1,i<<1); if(cover(p[i].second,p[j].second)) InserT(i<<1|1,j<<1),InserT(j<<1|1,i<<1); } for(int i=2;i<=(n<<1|1);i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) if(bel[i<<1]==bel[i<<1|1]) {puts("NO");return 0;} for(int k=2;k<=(n<<1|1);k++){ for(int i=G[k];i;i=E[i].nx) if(bel[E[i].t]!=bel[k]) Insert(bel[E[i].t],bel[k]); opp[bel[k]]=bel[k^1]; } memset(vis,0,sizeof(vis)); for(int i=1;i<=g;i++) if(!d[i]) Q.push(i); while(!Q.empty()){ int x=Q.front(); Q.pop(); if(!vis[x]) vis[x]=1,vis[opp[x]]=2; for(int i=nG[x];i;i=E[i].nx) if(!(--d[E[i].t])) Q.push(E[i].t); } puts("YES"); for(int i=1;i<=n;i++){ int s,s1,t,t1; if(vis[bel[i<<1|1]]==1){ s=p[i].first.first/60,s1=p[i].first.first%60; t=p[i].first.second/60,t1=p[i].first.second%60; printf("%02d:%02d %02d:%02d/n",s,s1,t,t1); } else{ s=p[i].second.first/60,s1=p[i].second.first%60; t=p[i].second.second/60,t1=p[i].second.second%60; printf("%02d:%02d %02d:%02d/n",s,s1,t,t1); } }}

HDU 2683

給定限制,求字典序最小解

O(NM)模板

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <queue>#define N 4010#define mp(a,b) make_pair(a,b)using namespace std;typedef pair<int,int> prs;typedef pair<prs,prs> prs4;prs4 p[N];int n,cnt,tp,ti,g;int G[N],sta[N],dfn[N],low[N],vis[N],bel[N],nG[N],v[N],d[N],opp[N];struct edge{ int t,nx;}E[N*N<<1];queue<int> Q;inline bool cover(prs a,prs b){ if(a.first>b.first) swap(a,b); return a.second>b.first;}inline void InserT(int x,int y){ E[++cnt].t=x;E[cnt].nx=G[y];G[y]=cnt;}inline void Insert(int x,int y){ E[++cnt].t=y;E[cnt].nx=nG[x];nG[x]=cnt;d[y]++;}void tarjan(int x){ vis[x]=1; dfn[x]=low[x]=++ti; sta[++tp]=x; for(int i=G[x];i;i=E[i].nx){ if(!vis[E[i].t]) tarjan(E[i].t); if(vis[E[i].t]==1) low[x]=min(low[x],low[E[i].t]); } if(low[x]==dfn[x]){ ++g; int k; do{ k=sta[tp--]; bel[k]=g; vis[k]=2; }while(tp&&k!=x); }}int main(){ freopen("t.in","r",stdin); freopen("t.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ int s,s1,t,t1,l; scanf("%d:%d %d:%d %d",&s,&s1,&t,&t1,&l); s=s*60+s1; t=t*60+t1; p[i]=mp(mp(s,s+l),mp(t-l,t)); } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ if(cover(p[i].first,p[j].first)) InserT(i<<1,j<<1|1),InserT(j<<1,i<<1|1); if(cover(p[i].first,p[j].second)) InserT(i<<1,j<<1),InserT(j<<1|1,i<<1|1); if(cover(p[i].second,p[j].first)) InserT(i<<1|1,j<<1|1),InserT(j<<1,i<<1); if(cover(p[i].second,p[j].second)) InserT(i<<1|1,j<<1),InserT(j<<1|1,i<<1); } for(int i=2;i<=(n<<1|1);i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) if(bel[i<<1]==bel[i<<1|1]) {puts("NO");return 0;} for(int k=2;k<=(n<<1|1);k++){ for(int i=G[k];i;i=E[i].nx) if(bel[E[i].t]!=bel[k]) Insert(bel[E[i].t],bel[k]); opp[bel[k]]=bel[k^1]; } memset(vis,0,sizeof(vis)); for(int i=1;i<=g;i++) if(!d[i]) Q.push(i); while(!Q.empty()){ int x=Q.front(); Q.pop(); if(!vis[x]) vis[x]=1,vis[opp[x]]=2; for(int i=nG[x];i;i=E[i].nx) if(!(--d[E[i].t])) Q.push(E[i].t); } puts("YES"); for(int i=1;i<=n;i++){ int s,s1,t,t1; if(vis[bel[i<<1|1]]==1){ s=p[i].first.first/60,s1=p[i].first.first%60; t=p[i].first.second/60,t1=p[i].first.second%60; printf("%02d:%02d %02d:%02d/n",s,s1,t,t1); } else{ s=p[i].second.first/60,s1=p[i].second.first%60; t=p[i].second.second/60,t1=p[i].second.second%60; printf("%02d:%02d %02d:%02d/n",s,s1,t,t1); } }}

表示本蒟蒻只會打模板,之前還把2-SAT搞成2-SET…… 之后還得學各種2-SAT亂搞


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 上犹县| 来凤县| 鞍山市| 和林格尔县| 出国| 阳原县| 东台市| 太白县| 丘北县| 方正县| 尼勒克县| 汝城县| 应用必备| 新昌县| 梅州市| 凤庆县| 上饶县| 民县| 桓台县| 若羌县| 崇左市| 铜鼓县| 榆社县| 奉节县| 彭泽县| 益阳市| 海原县| 房产| 章丘市| 吉林省| 武宁县| 开原市| 鄂托克前旗| 响水县| 丰台区| 临泉县| 古丈县| 贵州省| 九江市| 福建省| 长泰县|