Hướng dẫn giải của Thống nhất đất nước


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.

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 maxn 32032
#define maxm 72072
using namespace std;
int n,m,sm,cnt,rev[maxn],b[maxm],c[maxm],a[maxm*2],p[maxn],d[maxn],low[maxn],num[maxn];
int st[maxn],last,pl[maxn],l[maxn],pp[maxn],aa[maxm*2],f[maxn],e[maxn];

void visit(int x)
{
    int i; 
    st[++last]=x; low[x]=++cnt; num[x]=low[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;
    e[x]=1;
    fr(i,pp[x]+1,pp[x+1])
    {
       if (!e[aa[i]]) go(aa[i]);
       if (!f[aa[i]]) f[x]=0;
    }
    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 >> n >> m;
    n*=2;
    fr(i,1,n) 
    {
       rev[i]=i+n; rev[i+n]=i;
    }
    fr(i,1,m)
    {
       scanf("%d%d",&b[i],&c[i]);
       p[b[i]]++; p[c[i]]++;
    }    
    fr(i,1,n/2)
    {
       x=i*2-1; y=x+1;
       p[x]++; p[y]++; p[rev[x]]++; p[rev[y]]++;
       b[++m]=x; c[m]=y;
       b[++m]=rev[x]; c[m]=rev[y];
    }
    fr(i,2,n*2+1) p[i]+=p[i-1];
    fr(i,1,m)
    {
       a[p[b[i]]--]=rev[c[i]]; 
       a[p[c[i]]--]=rev[b[i]];
    }
    //strongly-connected components
    fr(i,1,n*2)
      if (!d[i]) visit(i);
    //check + create opposite vertex
    fr(i,1,n)
      if (d[i]==d[i+n])
      {
         cout << 0 << 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[b[i]]!=d[rev[c[i]]]) pp[d[b[i]]]++;
       if (d[c[i]]!=d[rev[b[i]]]) pp[d[c[i]]]++;
    }
    fr(i,2,sm+1) pp[i]+=pp[i-1];
    fr(i,1,m)
    {
       if (d[b[i]]!=d[rev[c[i]]]) aa[pp[d[b[i]]]--]=d[rev[c[i]]];
       if (d[c[i]]!=d[rev[b[i]]]) aa[pp[d[c[i]]]--]=d[rev[b[i]]];
    }
    //find result
    fr(i,1,sm) f[i]=-1;
    fr(i,1,sm)
      if (!e[i]) go(i);
    //out
    x=0;
    fr(i,1,n) x+=f[d[i]];
    if (x==n/2)
    {
       cout << 1 << endl;
       fr(i,1,n) 
         if (f[d[i]]) cout << i << " ";
         cout << endl;
    }
    else cout << 0 << 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 N = 8000, INF = 1e9;
int d[4*N], low[4*N], timed, n, m, iscc[4*N], nscc;
vector<int> g[4*N], scc[4*N];
bool choose[4*N];

void enter() {
    cin >> n >> m;
    for(int i = 0, u = 0, v = 2; i < n; ++i, u += 4, v += 4) {
        g[u].push_back(v | 1);
        g[u | 1].push_back(v);
        g[v].push_back(u | 1);
        g[v | 1].push_back(u);
    }
    for(int i = 0; i < m; ++i) {
        int u, v; cin >> u >> v; --u; --v;
        g[u << 1].push_back(v << 1 | 1);
        g[v << 1].push_back(u << 1 | 1);
    }
}

stack<int> st;
void tarjan(int u) {
    d[u] = low[u] = timed++;
    st.push(u);
    TR(g[u], v) if(d[*v] == -1)
        tarjan(*v), low[u] = min(low[u], low[*v]);
    else
        low[u] = min(low[u], d[*v]);
    if(d[u] == low[u]) {
        int v;
        do {
            v = st.top(); st.pop();
            iscc[v] = nscc;
            scc[nscc].push_back(v);
        } while(u != v);
        ++nscc;
    }
    d[u] = INF;
}

bool hasSolution() {
    for(int i = 0; i < 2*n; ++i)
        if(iscc[i << 1] == iscc[i << 1 | 1])
            return false;
    return true;
}

void trace() {
    fill(choose, choose + nscc, true);
    for(int i = 0; i < nscc; ++i) if(choose[i])
        TR(scc[i], j) choose[iscc[*j ^ 1]] = false;
    cout << 1 << '\n';
    for(int i = 0; i < 2*n; ++i)
        if(choose[iscc[i << 1]])
            cout << i+1 << ' ';
    cout << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    enter();
    fill(d, d+4*n, -1);
    for(int u = 0; u < 4*n; ++u) if(d[u] == -1) tarjan(u);
    if(hasSolution()) trace();
    else cout << 0 << '\n';
    return 0;
}

Code mẫu của ladpro98

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <stack>
#define neg(a) ((a) ^ 1)
const int N = 50000;
const int oo = 2000000000;
using namespace std;
vector<int> a[N], scc[N];
int low[N], d[N], lab[N];
bool was[N], pick[N];
int n, m, timer, nscc;

void addEdge(int u, int v) {
    a[u].push_back(neg(v));
    a[neg(v)].push_back(u);
}

stack<int> S;
void DFS(int u) {
    d[u] = ++timer;
    low[u] = oo;
    S.push(u);
    for(int i = 0; i < a[u].size(); i++) {
        int v = a[u][i];
        if (was[v]) continue;
        if (d[v]) low[u] = min(low[u], d[v]);
        else {
            DFS(v);
            low[u] = min(low[u], low[v]);
        }
    }
    if (low[u] >= d[u]) {
        int v;
        do {
            v = S.top();
            scc[nscc].push_back(v);
            lab[v] = nscc;
            was[v] = true;
            S.pop();
        } while (v != u);
        nscc++; 
    }
}

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    int u, v;
    for(int i = 0; i < n; i++) {
        addEdge(i << 2, (i << 2) + 2);
        addEdge((i << 2) + 2, i << 2);
    }
    for(int i = 1; i <= m; i++) {
        cin >> u >> v; u--; v--; 
        a[u << 1].push_back(neg(v << 1));
        a[v << 1].push_back(neg(u << 1));
    }
    for(int i = 0; i < (n << 2); i++)
        if (!was[i]) DFS(i);
    for(int i = 0; i < (n << 2); i += 2)
        if (lab[i] == lab[neg(i)]) {cout << 0; return 0;}
    for(int i = nscc - 1; i >= 0; i--) {
        bool mustTrue = false;
        for(int j = 0; j < scc[i].size(); j++)
            if (pick[scc[i][j]]) {mustTrue = true; break;}
        if (mustTrue) 
            for(int j = 0; j < scc[i].size(); j++)
                pick[scc[i][j]] = true;
        else 
            for(int j = 0; j < scc[i].size(); j++)
                pick[neg(scc[i][j])] = true;
    }
    cout << 1 << endl;
    for(int i = 0; i < (n << 2); i += 2)
        if (pick[i]) cout << (i >> 1) + 1 << ' ';
    return 0;
}

Code mẫu của RR

{$R+,Q+}
uses math;
const
  FINP='';
  FOUT='';
  MAXN=8001;
type
  list=^node;
  node=record
         u:longint;
         next:list;
       end;
var
  free,num,low,tp:array[-MAXN..MAXN] of longint;
  dd,choose,deg,h,hpos,stack:array[1..MAXN*2] of longint;
  ke:array[-MAXN..MAXN] of list;
  ke2,ds:array[1..MAXN*2] of list;
  sl,hsize,m,n,count,top:longint;
procedure finish; inline;
var
  f:text;
begin
  assign(f,FOUT); rewrite(f);
  writeln(f,'0');
  close(f);
  halt;
end;
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;
begin
  assign(f,FINP); reset(f);
  read(f,n,m);
  for i:=-n to n do ke[i]:=nil;
  for i:=1 to m do
    begin
      read(f,u,v);
      if u and 1=1 then u:=-((u+1) shr 1) else u:=(u+1) shr 1;
      if v and 1=1 then v:=-((v+1) shr 1) else v:=(v+1) shr 1;
      if u=-v then continue;
      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]]:=1;
  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 solve;
var
  i,u,v:longint;
  p,pp:list;
  f:text;
begin
  count:=0; top:=0;
  for i:=-n to n do
  if i<>0 then
    if num[i]=0 then dfs1(i);
  for i:=1 to n do
    if tp[i]=tp[-i] then finish;
  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;
  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;
  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;
  for i:=1 to n do
    if choose[i]=0 then finish;
  assign(f,FOUT); rewrite(f);
  writeln(f,1);
  for i:=1 to n do
    if choose[i]=1 then write(f,i shl 1,' ')
    else write(f,i shl 1-1,' ');
  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("elect.in","r",stdin);
//    freopen("elect.ou","w",stdout);
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++)
    {
        int u,v;  scanf("%d %d", &u, &v); u--;  v--;
        if ( (u ^ v) == 1) continue;
        edge.push_back(make_pair(u,v ^ 1));
        adj[u ^ 1].push_back(v);        
        edge.push_back(make_pair(v,u ^ 1));
        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("0\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;

    printf("1\n");
    for (int i = 0; i < n; i++) if (choose[i]) printf("%d ", 2 * i + 1); else printf("%d ", 2 * i + 2);
}

Code mẫu của skyvn97

#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define MAX   16161
#define f   first
#define s   second   
using namespace std;
typedef pair<int,int> ii;
stack<int> st;
//for the first graph
int m,n;
vector<int> g[MAX];
int low[MAX];
int num[MAX];
bool fre[MAX];
int ncp[MAX];
int res[MAX];
int time;
//for the second graph
int nc;
vector<int> comp[MAX];
vector<int> h[MAX];
int cnt;
bool vst[MAX];
int topo[MAX];
int mark[MAX];
ii lst[MAX];
void loadgraph_1st(void) {
    int i,j,u,v;
    scanf("%d",&n);
    scanf("%d",&m);
    for (i=1;i<=2*n;i=i+1) g[i].clear();
    for (i=1;i<=m;i=i+1) {
        scanf("%d",&u);
        scanf("%d",&v);
        g[u/2+(n+1)*(u%2)].push_back(v/2+v%2+(1-v%2)*n);
        g[v/2+(n+1)*(v%2)].push_back(u/2+u%2+(1-u%2)*n);
    }
    memset(low,0,sizeof low);
    memset(num,0,sizeof num);
    memset(fre,1,sizeof fre);   
    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) {
    time++;
    num[u]=time;
    low[u]=num[u];
    st.push(u);
    int i,v;
    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("0");
            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]]);
    memset(vst,true,sizeof vst);
    memset(mark,-1,sizeof mark);
    cnt=nc;
}
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 findres(void) {
    int i,j,u,v;
    for (i=1;i<=nc;i=i+1)
        if (vst[i]) {
            vst[i]=false;
            visit_2nd(i);
        }
    sort(&lst[1],&lst[nc+1]);
    for (i=1;i<=nc;i=i+1) {
        u=lst[i].s;
        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;
    printf("1\n");
    for (i=1;i<=n;i=i+1) res[i]=mark[ncp[i]];
    for (i=1;i<=n;i=i+1) {
        if (res[i]==1) printf("%d",2*i);
        else printf("%d",2*i-1);
        if (i<n) printf(" ");
    }
    printf("\n");
    printf("Em co biet khong he ve phuong hong dep lam\n");
    printf("Tinh minh cang nong tham cho bao uoc vong trao dang\n");
    printf("Gio trong tim toi, mau hong khong phai phoi\n");
    printf("Xuan qua he toi ta nho nhau luon phuong oi\n");
}
int main(void) {
    loadgraph_1st();
    tarjan();
    loadgraph_2nd();
    findres();
    print();
    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.