“假吗?”
“70pts TLE on #8#10#12”
“QWQ”
dfs找回路部分
stack<pair<int,int> > st;//first表示节点,second 表示其在环上的出边
bool vis[N],ex[N];
void dfs(int t,int s) {
for(int i=head[t];i;i=head[t])//找一条边(只找一条)
{
head[t]=nxt[i];//保证时间复杂度
int to=ver[i];
if(to==s||vis[i]) continue;//s为上一个节点 ,vis为1表示此边已经删除(被计算过了)
st.push(make_pair(t,i));ex[t]=1;//ex为1表示在栈中 ,此处为将当前节点入栈
if(ex[to]) //如果目标节点已经在栈中 (找到起点
{
k++;a[k].push_back(to);//加入答案序列(跟题目有关
while(st.top().first!=to)//弹出环内所有节点
{
r[st.top().first]-=2;//r是节点的度
vis[st.top().second]=1;ex[st.top().first]=0;//删除边,出栈节点
a[k].push_back(st.top().first);st.pop();//加入答案序列
}
//对环的起点 进行一样的操作
r[st.top().first]-=2;
vis[st.top().second]=1;ex[st.top().first]=0;
a[k].push_back(st.top().first);st.pop();
return;
}
dfs(to,t);
return;//只找一条边
}
}
int main()
{
rep(i,1,n) while(r[i])
{
dfs(i,0);
while(!st.empty())//清空栈里剩下的没能被计算的节点(是条链)
{
ex[st.top().first]=0;
st.pop();
}
}
}
也有可能是别的地方出锅了……(但我调了好几个小时了真没看出来)
完整代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string.h>
#include <stack>
#define rep(a,b,c) for(register int a=b;a<=c;++a)
using namespace std;
const int N=1e6+6;
int ver[N<<1],head[N],nxt[N<<1];
int Cnt;
int n,m;
void add(int u,int v) {
ver[Cnt]=v;
nxt[Cnt]=head[u];
head[u]=Cnt;
Cnt++;
}
inline char gc() {
static char BB[1000000],*S=BB,*T=BB;
return S==T&&(T=(S=BB)+fread(BB,1,1000000,stdin),S==T)?EOF:*S++;
}
inline int read() {
int x=0,f=1;
char ch=gc();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=gc();
}
while(ch<='9'&&ch>='0') {
x=x*10+ch-48;
ch=gc();
}
return x*f;
}
vector<int> a[N];
int k;
int r[N];
stack<pair<int,int> > st;//first表示节点,second 表示其在环上的出边
bool vis[N],ex[N];
void dfs(int t,int s) {
for(int i=head[t];i;i=head[t])//找一条边(只找一条)
{
head[t]=nxt[i];//保证时间复杂度
int to=ver[i];
if(to==s||vis[i]) continue;//s为上一个节点 ,vis为1表示此边已经删除(被计算过了)
st.push(make_pair(t,i));ex[t]=1;//ex为1表示在栈中 ,此处为将当前节点入栈
if(ex[to]) //如果目标节点已经在栈中 (找到起点
{
k++;a[k].push_back(to);//加入答案序列(跟题目有关
while(st.top().first!=to)//弹出环内所有节点
{
r[st.top().first]-=2;//r是节点的度
vis[st.top().second]=1;ex[st.top().first]=0;//删除边,出栈节点
a[k].push_back(st.top().first);st.pop();//加入答案序列
}
//对环的起点 进行一样的操作
r[st.top().first]-=2;
vis[st.top().second]=1;ex[st.top().first]=0;
a[k].push_back(st.top().first);st.pop();
return;
}
dfs(to,t);
return;//只找一条边
}
}
int main() {
// freopen("in.in","r",stdin);
n=read(),m=read();
int A,B,v;
rep(i,1,m) {
A=read();
B=read();
v=read()^read();
if(!v) continue;
add(A,B);add(B,A);
r[A]++;r[B]++;
}
rep(i,1,n)
if(r[i]&1) {
cout<<"NIE\n";
return 0;
}
rep(i,1,n) while(r[i])
{
dfs(i,0);
while(!st.empty())
{
ex[st.top().first]=0;
st.pop();
}
}
cout<<k<<"\n";
rep(i,1,k) {
cout<<a[i].size()-1<<" ";
rep(j,0,a[i].size()-1) cout<<a[i][j]<<" ";
cout<<"\n";
}
return 0;
}
大佬有更好写法的话请务必分享一下