#1468 : 2-SAT·hihoCoder新春晚会
时间限制:
10000ms
单点时限:
1000ms
内存限制:
256MB
-
3 2 1 3 2 4
样例输出
-
1 4 5
描述
hihoCoder新春晚会正在紧张地筹备中。晚会分为上半场和下半场,总导演小Hi现在要为N个节目安排演出时间(上半场或下半场)。为了描述方便,我们将第i个节目对应两个编号2i-1和2i,分别表示把第i个节目安排在上半场和下半场。
由于演员、道具和布景的限制。有些安排之间存在冲突,比如编号1的安排和编号4的安排有冲突,意味着"把第1个节目安排在上半场"同"把第2个节目安排在下半场"有冲突。
现在小Hi手里有M对编号,表示冲突的节目安排。他的任务是帮助主办方安排出节目演出的合理时间。
输入
第一行包含两个非负整数n和m(n≤8000,m≤20000),代表有n个节目和m对冲突。
接下来m行每行两个数x和y,表示编号x和编号y冲突。
输出
输出n行,每行一个数,从小到大输出最后进行演出的编号。若有多解,则输出字典序最小的。无解则输出NIE。
枚举每个点,然后通过正向边和反向边判断是否成立。
开始准备用强连通来写,无法得到最小字典序---然后GG-.-
有此情况:A --》 B A --》 B’ B --》 A’ B‘ --》A’
则下面代码错误-.-
附错误代码:
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
bool fafe[16100],da[16100];
int cmp[16100];
vector<int> V[16100],FV[16100],G,K[16100];
int ff(int b)
{
if ((b|1)==b) b++;
else b--;
return b;
}
void add_edge(int a,int b)
{
b=ff(b);
V[a].push_back(b);
FV[b].push_back(a);
}
void dfs(int x)
{
fafe[x]=true;
int v;
for (int i=0;i<V[x].size();i++)
{
v=V[x][i];
if (!fafe[v]) dfs(v);
}
G.push_back(x);
}
void fdfs(int x,int y)
{
K[y].push_back(x);
fafe[x]=true;
cmp[x]=y;
// printf("%d--------%d\n",x,y);
for (int i=0;i<FV[x].size();i++)
{
int v=FV[x][i];
if (!fafe[v]) fdfs(v,y);
}
}
int main()
{
int n,m,a,b;
scanf("%d%d",&n,&m);
while (m--)
{
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
memset(fafe,false,sizeof(fafe));
for (int i=1;i<=n*2;i++)
{
if (!fafe[i]) dfs(i);
}
memset(fafe,false,sizeof(fafe));
for (int i=G.size()-1;i>=0;i--)
{
if (!fafe[G[i]]) fdfs(G[i],i);
}
bool ans=false;
for (int i=1;i<2*n;i+=2)
{
if (cmp[i]==cmp[i+1])
{
ans=true;
break;
}
}
if (ans)
{
printf("NIE\n");
}
else
{
memset(da,false,sizeof(da));
memset(fafe,false,sizeof(fafe));/*
for (int i=1;i<=2*n;i++)
printf("%d %c",cmp[i],i==2*n?'\n':' ');*/
for (int i=1;i<=2*n;i++)
{
if (!fafe[i])
{
int hao=cmp[i],v;
for (int j=0;j<K[hao].size();j++)
{
v=K[hao][j];
da[v]=true;
fafe[v]=fafe[ff(v)]=true;
}
}
}
for (int i=1;i<=2*n;i++)
{
if (da[i])
printf("%d\n",i);
}
}
return 0;
}
所以就是 强连通判可行性,枚举搜索求解-.-(强连通部分可以去掉,直接在枚举时可判断有无解)。
代码:
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
bool fafe[261000];
int da[261000];
int cmp[261000];
vector<int> V[261000],FV[261000],G,K[261000],Q,W;
queue<int> que1,que2;
int ff(int b)
{
if ((b|1)==b) b++;
else b--;
return b;
}
void add_edge(int a,int b)
{
b=ff(b);
V[a].push_back(b);
FV[b].push_back(a);
}
void dfs(int x)
{
fafe[x]=true;
int v;
for (int i=0;i<V[x].size();i++)
{
v=V[x][i];
if (!fafe[v]) dfs(v);
}
G.push_back(x);
}
void fdfs(int x,int y)
{
K[y].push_back(x);
fafe[x]=true;
cmp[x]=y;
for (int i=0;i<FV[x].size();i++)
{
int v=FV[x][i];
if (!fafe[v]) fdfs(v,y);
}
}
int main()
{
int n,m,a,b;
scanf("%d%d",&n,&m);
while (m--)
{
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
memset(fafe,false,sizeof(fafe));
for (int i=1;i<=n*2;i++)
{
if (!fafe[i]) dfs(i);
}
memset(fafe,false,sizeof(fafe));
for (int i=G.size()-1;i>=0;i--)
{
if (!fafe[G[i]]) fdfs(G[i],i);
}
bool ans=false;
for (int i=1;i<2*n;i+=2)
{
if (cmp[i]==cmp[i+1])
{
ans=true;
break;
}
}
if (ans)
{
printf("NIE\n");
}
else
{
memset(da,0,sizeof(da));
memset(fafe,false,sizeof(fafe));
for (int i=1;i<=2*n;i++)
{
if (da[i]==0)
{
while (!que1.empty())
que1.pop();
while (!que2.empty())
que2.pop();
Q.clear();
W.clear();
que1.push(i);
que2.push(ff(i));
Q.push_back(i);
W.push_back(ff(i));
da[i]=1;
da[ff(i)]=2;
bool fa=true;
int v;
while (!que1.empty())
{
a=que1.front();
que1.pop();
for (int j=0;j<V[a].size();j++)
{
v=V[a][j];
if (da[v]==0)
{
que1.push(v);
que2.push(ff(v));
Q.push_back(v);
W.push_back(ff(v));
da[v]=1;
da[ff(v)]=2;
}
else if (da[v]==2)
{
fa=false;
break;
}
}
if (!fa) break;
while (!que2.empty())
{
a=que2.front();
que2.pop();
for (int j=0;j<FV[a].size();j++)
{
v=FV[a][j];
if (da[v]==0)
{
que2.push(v);
que1.push(ff(v));
W.push_back(v);
Q.push_back(ff(v));
da[v]=2;
da[ff(v)]=1;
}
else if (da[v]==1)
{
fa=false;
break;
}
}
if (!fa) break;
}
if (!fa) break;
}
if (!fa)
{
for (int i=0;i<Q.size();i++)
da[Q[i]]=0;
for (int i=0;i<W.size();i++)
da[W[i]]=0;
}
}
}
for (int i=1;i<=2*n;i++)
{
if (da[i]==1)
printf("%d\n",i);
}
}
return 0;
}