多测。所以少随几遍,反正正确率特别高。
考虑每组数据随20次点独立集,随20次边独立集。
随机方式应该是很经典的,随机打乱顺序之后直接贪心就行了。
因为它只要求到三分之一大小,所以还是很容易得出结论的。另外这题好像一定有解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include<bits/stdc++.h> using namespace std; mt19937 rd((unsigned long long)new char); int n,m,a[800005],vis[800005],ans[800005],tot; pair<int,int> p[600005]; vector<int> g[300005]; int main(){ ios::sync_with_stdio(0); int T;cin>>T; while(T--){ cin>>n>>m; fill(vis+1,vis+3*n+1,0); for(int i=1;i<=3*n;++i)a[i]=i,g[i].clear(); for(int i=1;i<=m;++i){ int x,y;cin>>x>>y;p[i]={x,y}; g[x].push_back(y);g[y].push_back(x); } int cnt=0; for(int st=1;st<=20;++st){ fill(vis+1,vis+3*n+1,0);shuffle(a+1,a+3*n+1,rd);cnt=0; for(int i=1;i<=3*n;++i){ if(!vis[a[i]]){ ans[++cnt]=a[i]; if(cnt==n){ cout<<"IndSet\n"; for(int j=1;j<=cnt;++j)cout<<ans[j]<<' '; cout<<'\n';goto ed; } for(int j:g[a[i]])vis[j]=1; } } } for(int i=1;i<=m;++i)a[i]=i; for(int st=1;st<=20;++st){ fill(vis+1,vis+m+1,0);shuffle(a+1,a+m+1,rd);cnt=0; for(int i=1;i<=m;++i){ int u=p[a[i]].first,v=p[a[i]].second; if(vis[u]||vis[v])continue; vis[u]=vis[v]=1;ans[++cnt]=a[i]; if(cnt==n){ cout<<"Matching\n"; for(int j=1;j<=cnt;++j)cout<<ans[j]<<' '; cout<<'\n';goto ed; } } } cout<<"Impossible\n"; ed:; } return 0; }
|