Hướng dẫn giải của Du lịch
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của flashmt
#include<iostream> #include<algorithm> #define fr(a,b,c) for (a=b;a<=c;a++) #define maxm 22222 #define maxn 16016 using namespace std; int n,m,b[maxm],c[maxm],a[maxm*2],p[maxn],d[maxn],sm,cnt,low[maxn],num[maxn]; int last,st[maxn],f[maxn],aa[maxm*2],pp[maxn],l[maxn],pl[maxn],rev[maxn],e[maxn]; void visit(int x) { int i; num[x]=++cnt; low[x]=cnt; st[++last]=x; fr(i,p[x]+1,p[x+1]) if (!d[a[i]]) { if (num[a[i]]) low[x]=min(low[x],num[a[i]]); else { visit(a[i]); low[x]=min(low[x],low[a[i]]); } } if (num[x]<=low[x]) { sm++; do { i=st[last--]; d[i]=sm; } while (i!=x); } } void go(int x) { int i; fr(i,pp[x]+1,pp[x+1]) { if (!e[aa[i]]) go(aa[i]); if (!f[aa[i]]) f[x]=0; } e[x]=1; if (f[x]<0) { f[x]=1; fr(i,pl[x]+1,pl[x+1]) f[l[i]]=0; } } int main() { int i,x,y; cin >> m >> n; fr(i,1,n*2) if (i<=n) rev[i]=i+n; else rev[i]=i-n; fr(i,1,m) { scanf("%d%d",&x,&y); if (x<0) x=n-x; if (y<0) y=n-y; b[i]=x; c[i]=y; p[rev[x]]++; p[rev[y]]++; } fr(i,2,n*2+1) p[i]+=p[i-1]; fr(i,1,m) { a[p[rev[b[i]]]--]=c[i]; a[p[rev[c[i]]]--]=b[i]; } //strongly-connected components fr(i,1,n*2) if (!d[i]) visit(i); //check condition + create opposite vertex fr(i,1,n) if (d[i]==d[i+n]) { cout << "NO" << endl; return 0; } else { pl[d[i]]++; pl[d[i+n]]++; } fr(i,2,sm+1) pl[i]+=pl[i-1]; fr(i,1,n) { l[pl[d[i]]--]=d[i+n]; l[pl[d[i+n]]--]=d[i]; } //union fr(i,1,m) { if (d[rev[b[i]]]!=d[c[i]]) pp[d[rev[b[i]]]]++; if (d[rev[c[i]]]!=d[b[i]]) pp[d[rev[c[i]]]]++; } fr(i,2,sm+1) pp[i]+=pp[i-1]; fr(i,1,m) { if (d[rev[b[i]]]!=d[c[i]]) aa[pp[d[rev[b[i]]]]--]=d[c[i]]; if (d[rev[c[i]]]!=d[b[i]]) aa[pp[d[rev[c[i]]]]--]=d[b[i]]; } //topo + find result fr(i,1,sm) f[i]=-1; fr(i,1,sm) if (!e[i]) go(i); //output int sl=0; fr(i,1,n) sl+=f[d[i]]; cout << "YES" << endl; cout << sl << endl; fr(i,1,n) if (f[d[i]]) cout << i << " "; cout << endl; return 0; }
Code mẫu của happyboy99x
#include<bits/stdc++.h> using namespace std; #define TR(v,i) for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i) const int M = 8000, INF = 1e9; int n, m, d[2*M], low[2*M], iscc[2*M], nscc, timed; vector<int> g[2*M], scc[2*M], sg[2*M]; bool choosescc[2*M]; int getVertice(int u) { return (abs(u)-1) << 1 | (u < 0 ? 1 : 0); } void enter() { cin >> n >> m; for(int i = 0; i < n; ++i) { int u, v; cin >> u >> v; u = getVertice(u); v = getVertice(v); g[u ^ 1].push_back(v); g[v ^ 1].push_back(u); } } stack<int> st; void dfs(int u) { st.push(u); low[u] = d[u] = timed++; TR(g[u], v) if(d[*v] == -1) dfs(*v), low[u] = min(low[u], low[*v]); else low[u] = min(low[u], d[*v]); if(low[u] == d[u]) { int v; do { v = st.top(); st.pop(); iscc[v] = nscc; scc[nscc].push_back(v); } while (v != u); ++nscc; } d[u] = INF; } void makeSuperGraph() { for(int u = 0; u < 2*m; ++u) TR(g[u], v) sg[iscc[u]].push_back(iscc[*v]); } bool mayHasSolution() { for(int u = 0; u < m; ++u) if(iscc[u << 1] == iscc[u << 1 | 1]) return false; return true; } void StrongConnectedComponent() { fill(d, d+2*m, -1); for(int u = 0; u < 2*m; ++u) if(d[u] == -1) dfs(u); } void trace() { fill(choosescc, choosescc + nscc, true); for(int i = 0; i < nscc; ++i) if(choosescc[i]) TR(scc[i], u) choosescc[iscc[*u ^ 1]] = false; int res = 0; for(int u = 0; u < m; ++u) if(choosescc[iscc[u << 1]]) ++res; cout << "YES\n" << res << '\n'; for(int u = 0; u < m; ++u) if(choosescc[iscc[u << 1]]) cout << u+1 << ' '; cout << '\n'; } int main() { ios::sync_with_stdio(false); enter(); StrongConnectedComponent(); if(mayHasSolution()) { makeSuperGraph(); trace(); } else cout << "NO\n"; return 0; }
Code mẫu của ladpro98
#include <bits/stdc++.h> const int N = 50000; using namespace std; int lab[N], st[N], low[N], num[N], res[N]; vector<int> a[N], com[N]; bool was[N], val[N]; int n, m, gap, nn, cnt, top, scc, k; void Enter() { scanf("%d %d\n", &m, &n); gap = n + 1; nn = n + gap; int i, v, u; for(i=1; i<=m; i++) { scanf("%d %d\n", &u, &v); a[-u + gap].push_back(v + gap); a[-v + gap].push_back(u + gap); } } void DFS(int u) { low[u] = num[u] = ++cnt; st[++top] = u; int i, v; for(i=0; i<a[u].size(); i++) { v = a[u][i]; if (was[v]) continue; if (num[v] != 0) low[u] = min(low[u], num[v]); else { DFS(v); low[u] = min(low[u], low[v]); } } if (num[u] == low[u]) { scc++; do { v = st[top--]; was[v] = true; lab[v] = scc; com[scc].push_back(v); } while (v != u); } } int main() { Enter(); int i, j, v; bool mustTrue; for(i=1; i<=nn; i++) if (num[i] == 0) DFS(i); for(i=1; i<=n; i++) if (lab[i + gap] == lab[-i + gap]) { printf("NO"); return 0; } for(i=scc; i; i--) { mustTrue = false; for(j=0; j<com[i].size(); j++) if (val[com[i][j]]) {mustTrue = true; break;} if (!mustTrue) { for(j=0; j<com[i].size(); j++) { v = com[i][j]; v = -(v - gap) + gap; val[v] = true; } } else { for(j=0; j<com[i].size(); j++) { v = com[i][j]; val[v] = true; } } } printf("YES\n"); for(i=1; i<=n; i++) if (val[i + gap]) res[++k] = i; printf("%d\n", k); for(i=1; i<=k; i++) printf("%d ", res[i]); return 0; }
Code mẫu của RR
{$R-,Q-} uses math; const FINP=''; FOUT=''; MAXN=20000; MAXM=16000; type list=^node; node=record u:longint; next:list; end; var hsize,sl,top,count,m,n:longint; free,tp,low,num:array[-MAXN..MAXN] of longint; choose,dd,stack,deg,h,hpos:array[1..MAXN*2] of longint; ke:array[-MAXN..MAXN] of list; ds,ke2:array[1..MAXN] of list; procedure add(u:longint;var a:list); inline; var p:list; begin new(p); p^.u:=u; p^.next:=a; a:=p; end; procedure inp; var f:text; i,u,v:longint; procedure finish; inline; begin close(f); assign(f,FOUT); rewrite(f); writeln(f,'NO'); close(f); halt; end; begin assign(f,FINP); reset(f); read(f,m,n); for i:=-n to n do ke[i]:=nil; for i:=1 to m do begin read(f,u,v); if u=-v then continue; if u=v then begin if u<0 then begin if choose[-u]=1 then finish; choose[-u]:=-1; end else begin if choose[u]=-1 then finish; choose[u]:=1; end; continue; end; add(v,ke[-u]); add(u,ke[-v]); end; close(f); end; procedure dfs1(u:longint); inline; var v:longint; p:list; begin inc(top); stack[top]:=u; inc(count); num[u]:=count; low[u]:=count; p:=ke[u]; while p<>nil do begin v:=p^.u; p:=p^.next; if free[v]=1 then continue; if num[v]=0 then begin dfs1(v); low[u]:=min(low[u],low[v]); end else low[u]:=min(low[u],num[v]); end; if num[u]=low[u] then begin inc(sl); ds[sl]:=nil; repeat v:=stack[top]; dec(top); tp[v]:=sl; free[v]:=1; add(v,ds[sl]); until v=u; end; end; procedure swap(var a,b:longint); inline; var temp:longint; begin temp:=a; a:=b; b:=temp; end; procedure downHeap(i:longint); inline; var j:longint; begin j:=i shl 1; while (j<=hsize) do begin if (j<hsize) and (deg[h[j+1]]<deg[h[j]]) then inc(j); if (deg[h[j]]<deg[h[i]]) then begin swap(hpos[h[i]],hpos[h[j]]); swap(h[i],h[j]); end; i:=j; j:=i shl 1; end; end; procedure upHeap(i:longint); inline; var j:longint; begin j:=i shr 1; while (i>1) and (deg[h[i]]<deg[h[j]]) do begin swap(hpos[h[i]],hpos[h[j]]); swap(h[i],h[j]); i:=j; j:=i shr 1; end; end; procedure push(u:longint); inline; begin inc(hsize); h[hsize]:=u; hpos[u]:=hsize; upHeap(hsize); end; procedure pop(var u:longint); inline; begin u:=h[1]; hpos[u]:=0; swap(h[1],h[hsize]); hpos[h[1]]:=0; dec(hsize); downHeap(1); end; procedure dfs2(u:longint); inline; var p:list; v:longint; begin if dd[u]=1 then exit; p:=ke2[u]; dd[u]:=1; while p<>nil do begin v:=p^.u; p:=p^.next; if dd[v]=1 then continue; dfs2(v); end; end; procedure finish; inline; var f:text; begin assign(f,FOUT); rewrite(f); writeln(f,'NO'); close(f); halt; end; procedure solve; var i,u,v:longint; p,pp:list; f:text; begin count:=0; {Xay dung cac thanh phan lien thong manh} for i:=-n to n do if i<>0 then if num[i]=0 then dfs1(i); {Neu co thanh phan lien thong chua ca dinh u va -u thi dung lai} for i:=1 to n do if tp[i]=tp[-i] then finish; {Tao do thi voi cac dinh la cac thanh phan lien thong manh} fillchar(dd,sizeof(dd),0); for i:=1 to sl do begin p:=ds[i]; while p<>nil do begin u:=p^.u; p:=p^.next; pp:=ke[u]; while pp<>nil do begin v:=pp^.u; pp:=pp^.next; if tp[v]=i then continue; add(i,ke2[tp[v]]); inc(deg[i]); end; end; end; {sort topo} hsize:=0; for i:=1 to sl do if dd[i]=0 then push(i); top:=0; while hsize>0 do begin pop(u); inc(top); stack[top]:=u; p:=ke2[u]; while p<>nil do begin v:=p^.u; p:=p^.next; if dd[v]=1 then continue; dec(deg[v]); upHeap(hpos[v]); end; end; {Xu ly} for i:=1 to n do if choose[i]=1 then begin tp[i]:=1; for u:=-n to n do if tp[u]=tp[i] then begin if u<0 then choose[-u]:=-1 else choose[u]:=1; dfs2(tp[-u]); end; end; for i:=1 to sl do begin u:=stack[i]; if dd[u]=1 then continue; dd[u]:=1; p:=ds[u]; while p<>nil do begin v:=p^.u; p:=p^.next; if v<0 then begin if choose[-v]=1 then finish; choose[-v]:=-1; end else begin if choose[v]=-1 then finish; choose[v]:=1; end; dfs2(tp[-v]); end; end; assign(f,FOUT); rewrite(f); for i:=1 to n do if choose[i]=0 then begin writeln(f,'NO'); close(f); halt; end; sl:=0; for i:=1 to n do if choose[i]=1 then inc(sl); writeln(f,'YES'); writeln(f,sl); for i:=1 to n do if choose[i]=1 then write(f,i,' '); close(f); end; begin inp; solve; end.
Code mẫu của ll931110
//#pragma comment(linker, "/STACK:16777216") #include <algorithm> #include <bitset> #include <cmath> #include <ctime> #include <cstdio> #include <cstdlib> #include <cstring> #include <deque> #include <fstream> #include <functional> #include <iostream> #include <map> #include <set> #include <sstream> #include <stack> #include <queue> #include <vector> #include <utility> using namespace std; int num[20010],low[20010],mark[20010],pos[20010],ou[20010],lab[20010]; bool exist[20010]; int m,n; int cnt,com = 0; bool choose[20010]; vector< pair<int,int> > edge; vector<int> adj[20010],rev[20010],element[20010]; stack<int> s; map< pair<int,int>,bool > mp; void DFS(int u) { num[u] = low[u] = ++cnt; s.push(u); for (int i = 0; i < adj[u].size(); i++) { int v = adj[u][i]; if (!exist[v]) continue; if (num[v] < 0) { DFS(v); low[u] = min(low[u],low[v]); } else low[u] = min(low[u],num[v]); } if (low[u] == num[u]) { while (1) { int x = s.top(); s.pop(); pos[x] = com; element[com].push_back(x); exist[x] = false; if (x == u) break; } com++; } } void toposort() { cnt = -1; queue<int> q; for (int i = 0; i < com; i++) if (!ou[i]) q.push(i); while (!q.empty()) { int u = q.front(); q.pop(); lab[++cnt] = u; for (int i = 0; i < rev[u].size(); i++) { int v = rev[u][i]; ou[v]--; if (!ou[v]) q.push(v); } } } void mark_false(int u) { for (int i = 0; i < rev[u].size(); i++) { int v = rev[u][i]; if (mark[v] < 0) { mark[v] = 0; mark_false(v); } } } int main() { // freopen("twosat.in","r",stdin); // freopen("twosat.ou","w",stdout); scanf("%d %d", &m, &n); for (int i = 0; i < m; i++) { int u,v; scanf("%d %d", &u, &v); if (u > 0) u = 2 * (u - 1); else u = 2 * (-u - 1) + 1; if (v > 0) v = 2 * (v - 1); else v = 2 * (-v - 1) + 1; if ( (u ^ v) == 1) continue; edge.push_back(make_pair(u ^ 1,v)); adj[u ^ 1].push_back(v); edge.push_back(make_pair(v ^ 1,u)); adj[v ^ 1].push_back(u); } memset(num,-1,sizeof(num)); cnt = -1; memset(exist,true,sizeof(exist)); for (int i = 0; i < 2 * n; i++) if (num[i] < 0) DFS(i); for (int i = 0; i < n; i++) if (pos[2 * i] == pos[2 * i + 1]) { printf("NO\n"); return 0; } for (int i = 0; i < com; i++) adj[i].clear(); memset(ou,0,sizeof(ou)); for (vector< pair<int,int> >::iterator it = edge.begin(); it != edge.end(); it++) { int u = pos[it->first],v = pos[it->second]; if (u == v || mp[make_pair(u,v)]) continue; mp[make_pair(u,v)] = true; ou[u]++; adj[u].push_back(v); rev[v].push_back(u); } toposort(); memset(mark,-1,sizeof(mark)); for (int i = 0; i < com; i++) if (mark[lab[i]] < 0) { mark[lab[i]] = 1; int first_element = element[lab[i]][0]; int alter = pos[first_element ^ 1]; mark[alter] = 0; mark_false(alter); } memset(choose,false,sizeof(choose)); for (int i = 0; i < com; i++) if (mark[i] > 0) for (int j = 0; j < element[i].size(); j++) if (element[i][j] % 2 == 0) choose[element[i][j]/2] = true; vector<int> ret; for (int i = 0; i < n; i++) if (choose[i]) ret.push_back(i + 1); printf("YES\n"); printf("%d\n", ret.size()); for (int i = 0; i < ret.size(); i++) printf("%d ", ret[i]); }
Code mẫu của skyvn97
#include<cstdio> #include<stack> #include<vector> #include<cstring> #include<algorithm> #define MAXN 8000 #define x first #define y second using namespace std; typedef pair<int,int> ii; stack<int> st; //for the first graph int m,n; vector<int> g[2*MAXN+7]; int low[2*MAXN+7]; int num[2*MAXN+7]; int ncp[2*MAXN+7]; bool fre[2*MAXN+7]; int res[2*MAXN+7]; int time; //for the second graph int nc; vector<int> h[2*MAXN+7]; vector<int> comp[2*MAXN+7]; int cnt; int topo[2*MAXN+7]; bool vst[2*MAXN+7]; int mark[2*MAXN+7]; ii lst[2*MAXN+7]; void loadgraph_1st(void) { scanf("%d",&m); scanf("%d",&n); int i,u,v; for (i=1;i<=n;i=i+1) { g[i].clear(); g[i+n].clear(); } for (i=1;i<=m;i=i+1) { scanf("%d",&u); scanf("%d",&v); if (u>0 && v>0) { g[u+n].push_back(v); g[v+n].push_back(u); } if (u>0 && v<0) { v=-v; g[u+n].push_back(v+n); g[v].push_back(u); } if (u<0 && v>0) { u=-u; g[u].push_back(v); g[v+n].push_back(u+n); } if (u<0 && v<0) { u=-u;v=-v; g[u].push_back(v+n); g[v].push_back(u+n); } } memset(fre,true,sizeof fre); memset(low,0,sizeof low); memset(num,0,sizeof num); time=0; nc=0; while (!st.empty()) st.pop(); } int min(const int &x,const int &y) { if (x<y) return (x); else return (y); } void visit_1st(const int &u) { int i,v; time++; num[u]=time; low[u]=num[u]; st.push(u); for (i=0;i<g[u].size();i=i+1) { v=g[u][i]; if (fre[v]) { if (num[v]>0) low[u]=min(low[u],num[v]); else { visit_1st(v); low[u]=min(low[u],low[v]); } } } if (low[u]==num[u]) { nc++; comp[nc].clear(); do { v=st.top();st.pop(); fre[v]=false; ncp[v]=nc; comp[nc].push_back(v); } while (v!=u); } } void tarjan(void) { int i; for (i=1;i<=2*n;i=i+1) if (num[i]==0) visit_1st(i); for (i=1;i<=n;i=i+1) if (ncp[i]==ncp[i+n]) { printf("NO"); exit(0); } } void loadgraph_2nd(void) { int i,j; for (i=1;i<=nc;i=i+1) h[i].clear(); for (i=1;i<=2*n;i=i+1) for (j=0;j<g[i].size();j=j+1) h[ncp[i]].push_back(ncp[g[i][j]]); cnt=nc; memset(vst,true,sizeof vst); } void visit_2nd(const int &u) { int i,v; for (i=0;i<h[u].size();i=i+1) { v=h[u][i]; if (vst[v]) { vst[v]=false; visit_2nd(v); } } cnt--; topo[u]=cnt; lst[u]=ii(-topo[u],u); } void sort_topo(void) { int i,j,u,v; for (i=1;i<=nc;i=i+1) if (vst[i]) { vst[i]=false; visit_2nd(i); } memset(mark,-1,sizeof mark); sort(&lst[1],&lst[nc+1]); for (i=1;i<=nc;i=i+1) { u=lst[i].y; if (mark[u]>=0) continue; mark[u]=1; for (j=0;j<comp[u].size();j=j+1) { v=comp[u][j]; if (v>n) mark[ncp[v-n]]=0; else mark[ncp[v+n]]=0; } } } void print(void) { int i,j; int nk=0; for (i=1;i<=2*n;i=i+1) res[i]=mark[ncp[i]]; for (i=1;i<=n;i=i+1) nk+=res[i]; printf("YES\n%d\n",nk); j=0; for (i=1;i<=n;i=i+1) if (res[i]==1) { printf("%d",i); j++; if (j<nk) printf(" "); } printf("\nSang thuc giac thay sao dep hon hom qua :D"); } int main(void) { loadgraph_1st(); tarjan(); loadgraph_2nd(); sort_topo(); print(); return 0; }
Bình luận