#define N 400005 #define M 400005 #define maxn 205 #define MOD 1000000000000000007 int n,m,k,t; bool vis[N],ans[N]; int v[M]; set<int> p[N]; priority_queue<pii> q; int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); while(S2(n,m)!=EOF) { while(!q.empty()) q.pop(); FI(n+1) p[i].clear(); fill(vis,false); fill(ans,false); FI(2 * m + 2) v[i] = -1; FI(n){ S(k); FJ(k){ S(t); v[t + m] = i; p[i].insert(t+m); } q.push(mp(-p[i].size(),i)); } bool flag = true; while(!q.empty()){ int top = q.top().second; q.pop(); if(vis[top]) continue; if(p[top].empty()){ flag = false; break; } int x = *p[top].begin(); vis[top] = true; ans[x] = true; int y = m + m - x; if(v[y] != -1 && !vis[v[y]]){ p[v[y]].erase(y); q.push(mp(-p[v[y]].size(),v[y])); } } if(flag){ printf("YES\n"); For(i,m+1,m+m+1) if(!ans[i]) printf("0"); else printf("1"); printf("\n"); } else { printf("NO\n"); } } //fclose(stdin); //fclose(stdout); return 0; }
第二种方法,用DFS找环,找到环的边后,用BFS确定,这个环所在的连通分量的所有边。如果,只出现x ~x,那么可以直接确定边,来推出整个连通分量其它的边。复杂度为o(n);
#define N 400005 #define M 400005 #define maxn 205 #define MOD 1000000000000000007 int n,m,k,t,all,from; int v[M],ans[N]; bool vis[N],Dvis[N]; vector<int> p[N]; queue<int> q; void BFS(){ while(!q.empty()){ int top = q.front(); q.pop(); FI(p[top].size()){ int g = p[top][i]; int gx = v[g]; if(ans[g] == -1 && ans[m + m - g] == -1){ ans[g] = 1;ans[m + m - g] = 0; if(!vis[gx]){ q.push(gx); vis[gx] = true; } } } } } bool DFS(int x,int fa){ all++; Dvis[x] = true; FI(p[x].size()){ int g = p[x][i]; int gx = v[g]; if((g != fa && g != m + m - fa) && ans[g] == -1 && ans[m + m - g] == -1){ if(Dvis[gx] || vis[gx]){ from = g; return true; } else if(DFS(gx,g)) return true; } } return false; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); while(S2(n,m)!=EOF) { FI(2 * m + 2) v[i] = -1,ans[i] = -1; fill(vis,false); fill(Dvis,false); FI(n){ S(k); FJ(k){ S(t); if(v[t+m] != -1){ vis[v[t+m]] = 1; vis[i] = 1; ans[t+m] = 1; } else v[t + m] = i; } } For(i,m + 1,m + m + 1){ if(v[i] >= 0 && v[m + m - i] >= 0){ int s = v[i],e = v[m + m -i]; p[s].push_back(m + m - i); p[e].push_back(i); } else if(v[i] >= 0 && v[m + m - i] == -1){ ans[i] = 1;ans[m + m - i] = 0;vis[v[i]] = true; } else if(v[i] == -1 && v[m + m - i] >= 0){ ans[m + m - i] = 1;ans[i] = 0;vis[v[m + m - i]] = true; } } while(!q.empty()) q.pop(); FI(n){ if(vis[i]){ q.push(i); } } BFS(); bool flag = true; FI(n){ if(!vis[i] && !Dvis[i]){ from = -1;all = 0; DFS(i,-1); if(all >= 2 && from == -1) { flag = false; break; } if(from != -1){ ans[from] = 1;ans[m + m - from] = 0; while(!q.empty()) q.pop(); q.push(v[from]); BFS(); } } } if(flag){ printf("YES\n"); For(i,m+1,m+m+1) if(ans[i] == 1) printf("1"); else printf("0"); printf("\n"); } else { printf("NO\n"); } } //fclose(stdin); //fclose(stdout); return 0; }