您的位置:首页 > 运维架构

Hdu 5348 MZL's endless loop (构造)

2016-07-13 21:02 381 查看
解析:

每找到一个单个的环,将其指定顺序后从图中出,最后会得到一个森林,对于每一棵树,从根节点开始根据出入大小指定方向即可。注意实现细节!

[code]:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>

using namespace std;
typedef pair<int,int> P;
const int maxn = 1e5+5;
const int maxm = 3e5+5;

struct Nod{
int b,next,id;
void init(int b,int next,int id){
this->b=b;this->next=next;this->id=id;
}
}buf[2*maxn];
int n,m,len,E[maxn],ans[maxm],del[maxm],instack[maxn],used[maxn];
int out[maxn],in[maxn];
queue<P> G[maxn];

void init(){
len = 0;
memset(E,-1,(n+1)*sizeof(int));
memset(del,0,m*sizeof(int));
memset(used,0,(n+1)*sizeof(int));
memset(out,0,(n+1)*sizeof(int));
memset(in,0,(n+1)*sizeof(int));
for(int i = 1;i <= n;i++) while(!G[i].empty()) G[i].pop();
}
void add_edge(int a,int b,int c){
buf[len].init(b,E[a],c);E[a]=len++;
buf[len].init(a,E[b],c^1);E[b]=len++;
}
int findCircle(int u){
int i,v,c;
if(instack[u]) return u;
instack[u] = 1;
while(!G[u].empty()){
P p = G[u].front();G[u].pop();
v = p.first;i = p.second;
if(del[i/2]) continue;
del[i/2] = 1;
c = findCircle(v);
if(c != -1&&c != u){
ans[i/2] = i&1;
instack[u] = 0;
return c;
}else if(c == u) ans[i/2] = i&1;
else add_edge(u,v,i);
}
instack[u] = 0;
return -1;
}
void dfs(int u,int pre){
int i,v,id;
used[u] = 1;
for(i = E[u];i != -1;i = buf[i].next){
v = buf[i].b;id = buf[i].id;
if(v == pre) continue;
if(out[u]>in[u]) ans[id/2]=1^(id&1),in[u]++,out[v]++;
else ans[id/2] = 0^(id&1),out[u]++,in[v]++;
dfs(v,u);
}
}

int main(){
int i,j,cas,u,v;
scanf("%d",&cas);
while(cas--){
scanf("%d%d",&n,&m);
init();
for(i = 0;i < m;i++){
scanf("%d%d",&u,&v);
G[u].push(P(v,2*i));
G[v].push(P(u,2*i+1));
}
for(i = 1;i <= n;i++) findCircle(i);
for(i = 1;i <= n;i++){
if(used[i]) continue;
dfs(i,-1);
}
for(i = 0;i < m;i++) printf("%d\n",ans[i]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: