# tarjan/2-sat

tarjan求割点板子

#include <bits/stdc++.h>
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
#define Fanv(x) for(int i=edge::sum[x-1]+1,now_v=edge::e[i].y;i<=edge::sum[x];i++,now_v=edge::e[i].y)  //For_all_neighbor_vertex 枚举x的所有邻居,now_v=当前枚举的邻居
const int N=100000,M=200000,type=0;//点数，边数最大值(开空间用),有向图type=0，无向图为1
using namespace std;
namespace Fast_IO {
int x(0);
char ch(getchar());
while(ch>'9'||ch<'0')ch=getchar();
while(ch<='9'&&ch>='0') {
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
}
namespace edge {
int n,m,sum[N+1],cnt(0);
struct element {
int x,y,len;//边的起点，终点，边权
bool operator < (const element a)const {
if(x!=a.x)return x<a.x;
else return y<a.y;
}
} e[(1+type)*M+1];
inline void add_edge(int st,int en,int val) {
e[++cnt].x=st;
e[cnt].y=en;
e[cnt].len=val;
}
void work() {
e[0].x=e[0].y=0;
sum[0]=0;
std::sort(e+1,e+cnt+1);
for(int i=1; i<=cnt; i++) {
if(e[i].x!=e[i+1].x) {
sum[e[i].x]=i;
}
}
for(int i=1; i<=n; i++)sum[i]=max(sum[i],sum[i-1]);
}
void reset() {
cnt=0;
}
}
namespace Tarjan {
int dfn[N+1],low[N+1],col[N+1],s[N+1],b[N+1],cnt(0),cnt_col(0),cnt_sta(0);
int cut[N+1];
void dfs(int now,int fa) {
dfn[now]=low[now]=++cnt;
s[++cnt_sta]=now;
b[now]=1;
cut[now]=0;
int num_child(0);
Fanv(now) {
if(now_v!=fa) {
if(!dfn[now_v]) {
dfs(now_v,now);
low[now]=min(low[now],low[now_v]);
if(low[now_v]>=dfn[now]&&fa)cut[now]=1;
++num_child;
}
low[now]=min(low[now],dfn[now_v]);
}
}
if(dfn[now]==low[now]) {
int now_col=++cnt_col;
while(s[cnt_sta]!=now) {
col[s[cnt_sta]]=now_col;
b[s[cnt_sta]]=0;
--cnt_sta;
}
col[s[cnt_sta]]=now_col;
b[s[cnt_sta]]=0;
--cnt_sta;
}
if(fa==0&&num_child>=2)cut[now]=1;
}
void work() {
for(int i=1; i<=edge::n; i++) {
if(!dfn[i])dfs(i,0);
}
}
}
int main() {
//	freopen("P3388_1.in","r",stdin);
//	freopen("1.out","w",stdout);
for(int i=1; i<=edge::m; i++) {
int x,y,len;
}
edge::work();
Tarjan::work();
int ans(0);
for(int i=1; i<=edge::n; i++) {
ans+=Tarjan::cut[i];
}
cout<<ans<<endl;
for(int i=1; i<=edge::n; i++) {
if(Tarjan::cut[i])cout<<i<<" ";
}
return 0;
}


2-sat板子

#include <bits/stdc++.h>
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
#define Fanv(x) for(int i=edge::sum[x-1]+1,now_v=edge::e[i].y;i<=edge::sum[x];i++,now_v=edge::e[i].y)  //For_all_neighbor_vertex 枚举x的所有邻居,now_v=当前枚举的邻居
const int N=2000000,M=2000000;//点数，边数最大值(开空间用),有向图type=0，无向图为1
using namespace std;
namespace Fast_IO {
int x(0);
char ch(getchar());
while(ch>'9'||ch<'0')ch=getchar();
while(ch<='9'&&ch>='0') {
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
}
namespace edge {
int n,m,sum[N+1],cnt(0);
struct element {
int x,y,len;//边的起点，终点，边权
bool operator < (const element a)const {
if(x!=a.x)return x<a.x;
else return y<a.y;
}
} e[M+1];
inline void add_edge(int st,int en,int val) {
e[++cnt].x=st;
e[cnt].y=en;
e[cnt].len=val;
}
void work() {
e[0].x=e[0].y=0;
sum[0]=0;
std::sort(e+1,e+cnt+1);
for(int i=1; i<=cnt; i++) {
if(e[i].x!=e[i+1].x) {
sum[e[i].x]=i;
}
}
for(int i=1; i<=n; i++)sum[i]=max(sum[i],sum[i-1]);
}
void reset() {
cnt=0;
}
}
namespace Tarjan {
int dfn[N+1],low[N+1],col[N+1],s[N+1],b[N+1],cnt(0),cnt_col(0),cnt_sta(0);
//	int cut[N+1];
void dfs(int now,int fa) {
dfn[now]=low[now]=++cnt;
s[++cnt_sta]=now;
b[now]=1;
//		cut[now]=0;
int num_child(0);
Fanv(now) {
if(now_v!=fa) {
if(!dfn[now_v]) {
dfs(now_v,now);
low[now]=min(low[now],low[now_v]);
//					if(low[now_v]>=dfn[now]&&fa)cut[now]=1;
++num_child;
}
else if(b[now_v])low[now]=min(low[now],dfn[now_v]);
}
}
if(dfn[now]==low[now]) {
++cnt_col;
while(s[cnt_sta]!=now) {
col[s[cnt_sta]]=cnt_col;
b[s[cnt_sta]]=0;
--cnt_sta;
}
col[s[cnt_sta]]=cnt_col;
b[s[cnt_sta]]=0;
--cnt_sta;
}
//		if(fa==0&&num_child>=2)cut[now]=1;
}
void work() {
memset(dfn,0,sizeof(dfn));
for(int i=1; i<=edge::n; i++) {
if(!dfn[i])dfs(i,0);
}
}
}
int main() {
//	freopen("P3388_1.in","r",stdin);
//	freopen("1.out","w",stdout);
for(int i=1; i<=edge::m/2; i++) {
int x,y,a,b;
}
edge::work();
Tarjan::work();
for(int i=1; i<=edge::n/2; i++)if(Tarjan::col[i]==Tarjan::col[i+edge::n/2]) {
cout<<"IMPOSSIBLE"<<endl;
return 0;
}
cout<<"POSSIBLE"<<endl;
for(int i=1; i<=edge::n/2; i++) {
cout<<(Tarjan::col[i]>Tarjan::col[i+edge::n/2])<<" ";
}
return 0;
}

posted @ 2022-04-29 17:18  永无岛  阅读(28)  评论(0编辑  收藏  举报