zoukankan      html  css  js  c++  java
  • Gym-102001,2018 ICPC Asia Jakarta Regional Contest K Boomerangs

    题意

    给一个(n)个点(m)条边的无向图(G=(V,E)),让你找最多有多少个回力镖,回力镖是一个三元组((u,v,w))表示边((u,v)subseteq E)且边((v,w)subseteq E),每个边只能存在于一个回力镖中。

    分析

    dfs深搜,回溯过程中将当前结点(u)的前向边两两组成回力镖,如果多出了一条边就和u的父亲组成回力镖,这样构造最多会浪费每次dfs的根节点连的一条前向边,所以总答案为每个连通块的边数向下整除2的和。

    Code

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<iomanip>
    #include<sstream>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<bitset>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<set>
    #include<map>
    #define rep(i,x,n) for(int i=x;i<=n;i++)
    #define per(i,n,x) for(int i=n;i>=x;i--)
    #define sz(a) int(a.size())
    #define rson mid+1,r,p<<1|1
    #define pii pair<int,int>
    #define lson l,mid,p<<1
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define se second
    #define fi first
    using namespace std;
    const double eps=1e-8;
    const int mod=1e9+7;
    const int N=1e5+10;
    const int inf=1e9;
    int n,m;
    set<int>g[N],p[N];
    int d[N],vis[N],f[N];
    vector<pair<pii,int> >ans;
    void dfs(int u){
    	d[u]=d[f[u]]+1;
    	for(int x:g[u]){
    		if(vis[x]) continue;
    		vis[x]=1;
    		f[x]=u;
    		dfs(x);
    	}
    	vector<int>q;
    	for(int x:p[u]){
    		if(x!=f[u]) q.pb(x);
    	}
    	for(int i=0;i+1<sz(q);i+=2){
    		ans.pb(mp(mp(q[i],u),q[i+1]));
    		p[u].erase(q[i]);
    		p[u].erase(q[i+1]);
    		p[q[i]].erase(u);
    		p[q[i+1]].erase(u);
    	}
    	if(sz(q)%2!=0&&f[u]!=0){
    		int x=q[sz(q)-1];
    		ans.pb(mp(mp(x,u),f[u]));
    		p[u].erase(x);
    		p[x].erase(u);
    		p[f[u]].erase(u);
    		p[u].erase(f[u]);
    	}
    }
    int main(){
    	//ios::sync_with_stdio(false);
    	//freopen("in","r",stdin);
    	scanf("%d%d",&n,&m);
    	rep(i,1,m){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		g[x].insert(y);
    		g[y].insert(x);
    		p[x].insert(y);
    		p[y].insert(x);
    	}
    	for(int i=1;i<=n;i++){
    		if(!vis[i]){
    			vis[i]=1;
    			dfs(i);
    		}
    	}
    	printf("%d
    ",sz(ans));
    	for(auto x:ans){
    		printf("%d %d %d
    ",x.fi.fi,x.fi.se,x.se);
    	}
    	return 0;
    }
    
  • 相关阅读:
    array_merge
    漏斗模型
    3 破解密码,xshell连接
    2-安装linux7
    1-Linux运维人员要求
    17-[模块]-time&datetime
    16-[模块]-导入方式
    Nginx服务器
    15-作业:员工信息表查询
    14-本章总结
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13269905.html
Copyright © 2011-2022 走看看