【POI2011】Garbage

Face questions

https://loj.ac/problem/2162

answer

Water problem, first of all same side need only one, if one side appears twice in a loop, the direct deleted also satisfy the judgment.

Direct Euler tour.

#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100050
#define ri register int
using namespace std;

you n, m, and, v, ms, mt, in [N], vis [N];
stack<int> s;
int cur[N],deg[N];
vector<int> ed[N],vv,to;

inline int read() {
  int ret=0,f=0; char ch=getchar();
  while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
  while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
  return f?-ret:ret;
}

int getf(int x) {
  if (x==f[x]) return x;
  return f[x]=getf(f[x]);
}

void add_edge(int u,int v) {
  f[getf(u)]=getf(v);
  to.push_back(v); vv.push_back(0); ed[u].push_back(to.size()-1);
  to.push_back(u); vv.push_back(0); ed[v].push_back(to.size()-1);
  you [u] ++; provides [v] ++ ;
}

void euler1(int x) {
  for (ri &i=cur[x];i<ed[x].size();i++) {
    int e=ed[x][i];
    if (vv[e]) continue;
    vv [e] = vv [ 1 ^ e] = 1 ;
    euler1(to[e]);
    s.push(to[e]);
  }
}

int main () {
  n=read(); m=read();
  for (ri i=1;i<=n;i++) f[i]=i;
  for (ri i=1;i<=m;i++) {
    u=read(),v=read(),ms=read(),mt=read();
    if (ms!=mt) add_edge(u,v);
  }
  for (ri i=1;i<=n;i++) if (deg[i]&1) {
    puts("NIE");
    return 0;
  }
  int ans=0;
  for (ri i=1;i<=n;i++) if (i!=getf(i)) {
    if (!vis[getf(i)]) ans++;
    view [getf (i)] = 1 ;
  }
  printf("%d\n",ans);
  for (ri i=1;i<=n;i++) {
    if (vis[getf(i)]==2 || vis[getf(i)]==0) continue;
    view [getf (i)] = 2 ;
    euler1 (i);
    printf("%d ",s.size());
    printf("%d ",i);
    while (!s.empty()) printf("%d ",s.top()),s.pop();
    puts("");
  }
  return 0;
}

 

Guess you like

Origin www.cnblogs.com/shxnb666/p/11349683.html