結果

問題 No.1553 Lovely City
ユーザー suzuken_wsuzuken_w
提出日時 2021-07-08 20:14:43
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 5,674 bytes
コンパイル時間 3,490 ms
コンパイル使用メモリ 239,312 KB
実行使用メモリ 75,308 KB
最終ジャッジ日時 2023-09-14 04:50:38
合計ジャッジ時間 18,113 ms
ジャッジサーバーID
(参考情報)
judge11 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,356 KB
testcase_01 AC 2 ms
4,352 KB
testcase_02 AC 6 ms
10,084 KB
testcase_03 AC 2 ms
4,376 KB
testcase_04 AC 2 ms
4,380 KB
testcase_05 AC 2 ms
4,376 KB
testcase_06 AC 2 ms
4,380 KB
testcase_07 AC 2 ms
4,500 KB
testcase_08 AC 161 ms
46,868 KB
testcase_09 WA -
testcase_10 AC 180 ms
53,516 KB
testcase_11 WA -
testcase_12 WA -
testcase_13 AC 154 ms
41,080 KB
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 AC 130 ms
41,324 KB
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#pragma GCC optimize("O3")
#include<bits/stdc++.h> 
using namespace std;
using ll=long long;
using lll=__int128_t;
using P=pair<ll,ll>;
template<class T> using V=vector<T>; 
#define fi first
#define se second
#define all(v) (v).begin(),(v).end()
const ll inf=(1e18);
//const ll mod=998244353;
const ll mod=1000000007;
const vector<int> dy={-1,0,1,0},dx={0,-1,0,1};
ll GCD(ll a,ll b) {return b ? GCD(b,a%b):a;}
ll LCM(ll c,ll d){return c/GCD(c,d)*d;}
struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}} __init;
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T>void debag(const vector<T> &a){cerr<<"debag :";for(auto v:a)cerr<<v<<" ";cerr<<"\n";}
template<class T>void print(const vector<T> &a){for(auto v:a)cout<<v<<" ";cout<<"\n";}
std::ostream &operator<<(std::ostream &dest, __int128_t value) {
  std::ostream::sentry s(dest);
if (s) {__uint128_t tmp = value < 0 ? -value : value;char buffer[128];char *d = std::end(buffer);do {--d;*d = "0123456789"[tmp % 10];tmp /= 10;} while (tmp != 0);
if (value < 0) { --d; *d = '-';}int len = std::end(buffer) - d;if (dest.rdbuf()->sputn(d, len) != len) {dest.setstate(std::ios_base::badbit);}}
  return dest;}
class UF{
public:
	vector<int> par,num;
	int find(int v){
		return (par[v]==v)? v: (par[v]=find(par[v]));
	}
  explicit UF(){}
	explicit UF(int N):par(N),num(N,1){
		iota(all(par),0);
	}
  void init(int N){
     par.assign(N,0);
     num.assign(N,1);
     iota(all(par),0);
  }
	void unite(int u,int v){
		u=find(u),v=find(v);
		if(u==v)return;
		if(num[u]<num[v])swap(u,v);
		num[u]+=num[v];
		par[v]=u;
	}
	bool same(int u,int v){
		return find(u)==find(v);
	}
	bool ispar(int v){
		return v==find(v);
	}
	int size(int v){
		return num[find(v)];
	}
};
template<typename G>
struct SCC{
    int n;
    const G &g;
    vector<vector<int>> gg,rg;
    vector<int> cmp,ord,used;

    SCC(G &g):n(g.size()),g(g),gg(g.size()),rg(g.size()),cmp(g.size(),-1),used(g.size(),false){
        for(int i=0;i<n;i++){
            for(int v:g[i]){
                gg[i].emplace_back(v);
                rg[v].emplace_back(i);
            }
        }
    }

    int operator[](int k){
        return cmp[k];
    }

    void dfs(int id){
        if(used[id])return ;
        used[id]=true;
        for(int v:gg[id])dfs(v);
        ord.emplace_back(id);
    }
     void rdfs(int id,int cnt){
        if(cmp[id]!=-1)return ;
        cmp[id]=cnt;
        for(int v:rg[id])rdfs(v,cnt);
    }

    void build(vector<vector<int>> &t){
        for(int i=0;i<n;i++)dfs(i);
        reverse(ord.begin(),ord.end());
        int ptr=0;
        for(int v:ord){
            if(cmp[v]==-1){
                rdfs(v,ptr);
                ptr++;
            }
        }
        t.resize(ptr);
        for(int i=0;i<n;i++){
            for(int v:g[i]){
                if(cmp[i]==cmp[v])continue;
                t[cmp[i]].emplace_back(cmp[v]);
            }
        }
    }
};
struct tposort{
	int n;
	vector<vector<int> > G;
	vector<int> deg,res;
	tposort(int node_size):n(node_size), G(n), deg(n, 0){}
	
    void add_edge(int from,int to){
		G[from].push_back(to);
		deg[to]++;
	}
	bool solve(){
		queue<int> q;
		for(int i = 0; i < n; i++){
			if(deg[i] == 0){
				q.push(i);
			}
		}
		while(!q.empty()){
			int cur = q.front();
			q.pop();
			res.push_back(cur);
			for(int v :G[cur]){
				if(--deg[v]==0){
					q.push(v);
				}
			}
		}
		return (*max_element(deg.begin(),deg.end()) == 0);
	}
};
int main(){
      int n,m;
      cin>>n>>m;
      UF uf(n);
      V<P> a(m);
      for(int i=0;i<m;i++){
            cin>>a[i].fi>>a[i].se;
            a[i].fi--;a[i].se--;
            uf.unite(a[i].fi,a[i].se);
      }
      V<V<P>> d(n);
      for(int i=0;i<m;i++){
             d[uf.find(a[i].fi)].emplace_back(a[i]);
      }
      V<int> id(n);
      V<P> ans;
      V<bool> used(n,false);
      for(int i=0;i<n;i++){
            if(uf.find(i)!=i)continue;
            if(uf.size(i)==1)continue;
            int cnt=0;
            for(auto &p:d[i]){
                  if(!used[p.fi]){
                        id[p.fi]=cnt++;
                        used[p.fi]=true;
                  }
                  if(!used[p.se]){
                        id[p.se]=cnt++;
                        used[p.se]=true;
                  }
            }
            V<V<int>> g(cnt),tmp;
            V<int> rid(cnt);
            for(auto &p:d[i]){
                   rid[id[p.fi]]=p.fi+1;rid[id[p.se]]=p.se+1;
                   g[id[p.fi]].emplace_back(id[p.se]);
            }
            SCC<V<V<int>>> scc(g);
            scc.build(tmp);
            int sz=tmp.size();
            V<V<int>> node(sz);
            for(int j=0;j<cnt;j++){
                   node[scc[j]].emplace_back(rid[j]);
            }
            tposort tp(sz);
            for(int j=0;j<sz;j++){
                  for(int v:tmp[j])tp.add_edge(j,v);
            }
            if(!tp.solve())exit(1);
            int siz=tp.res.size();
           // print(tp.res);
            for(int j=0;j<siz-1;j++){
                  ans.emplace_back(node[tp.res[j]].front(),node[tp.res[j+1]].front());
            }
            for(int j=0;j<sz;j++){
                   siz=node[j].size();
                   if(siz==1)continue;
                   for(int k=0;k<siz;k++){
                          int cur=node[j][k],to=node[j][(k+1)%siz];
                          ans.emplace_back(cur,to);
                   }
            }
       }
       cout<<ans.size()<<"\n";
       for(auto &p:ans)cout<<p.fi<<" "<<p.se<<"\n";
}
0