2021上海L Three,Three,Three(一般图匹配)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021上海L Three,Three,Three(一般图匹配)相关的知识,希望对你有一定的参考价值。
2021上海L Three,Three,Three(一般图匹配)
给定 所有点度数为3的无向图,将 m m m条边 其分成 m 3 \\dfracm3 3m 条长度为 3 3 3的链。
定理:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n)
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
template <typename T> //x=max(x,y) x=min(x,y)
void cmx(T &x,T y)
if(x<y) x=y;
template <typename T>
void cmn(T &x,T y)
if(x>y) x=y;
struct Blossom_Tree
vector<int>e[N];
queue<int>q;
int mh[N],pre[N],s[N],id[N],vis[N],n,num;
void init(int nn) //初始化
n=nn,num=0;
for(int i=1;i<=n;i++) e[i].clear(),mh[i]=pre[i]=vis[i]=s[i]=id[i]=0;
void add(int u,int v)
e[u].push_back(v),e[v].push_back(u);
int find(int x) return s[x]==x?x:s[x]=find(s[x]);
int LCA(int x,int y) //求LCA.
for(++num;;swap(x,y))
if(x)
if(id[x=find(x)]==num) return x;//在同一个奇环肯定能找到被编号的结点.
id[x]=num,x=pre[mh[x]]; //沿增广路径的非匹配边向上走直到找到祖先.
void blossom(int x,int y,int rt) //缩点(开花) O(n)
while(find(x)!=rt)
pre[x]=y,y=mh[x];
if(vis[y]==2) vis[y]=1,q.push(y);//如果奇环上有2型结点 就变为1型结点加入队列.
if(find(x)==x) s[x]=rt;//只对根处理.
if(find(y)==y) s[y]=rt;
x=pre[y];
bool aug(int st) //求增广路径.O(n)
for(int i=1;i<=n;i++) vis[i]=pre[i]=0,s[i]=i;
while(!q.empty()) q.pop();
q.push(st),vis[st]=1;
while(!q.empty())
int u=q.front();q.pop();
for(auto v:e[u])
if(find(u)==find(v)||vis[v]==2) continue;//如果是已经缩点了或者是偶环直接继续,没有影响.
if(!vis[v]) //如果没有被染色
vis[v]=2,pre[v]=u;
if(!mh[v]) //如果未被匹配,就进行匹配
for(int x=v,last;x;x=last) //增广路取反
last=mh[pre[x]],mh[x]=pre[x],mh[pre[x]]=x;
return 1;
vis[mh[v]]=1,q.push(mh[v]); //否则将v的匹配结点染色,加入队列.
else
int rt=LCA(u,v); //找到LCA ,然后进行缩点.
blossom(u,v,rt),blossom(v,u,rt);
return 0;
int cal()
int ans=0;
for(int i=1;i<=n;i++) if(!mh[i]&&aug(i)) ans++; //最大匹配.
return ans;
T;
int deg[N][N],n,m;
bitset<N>vis;
int que[N],tp;
int pre[N];
void dfs(int u)
vis[u]=1;que[tp++]=u;
for(int i=1;i<=n;i++) if(!vis[i]&°[u][i]) dfs(i);
int main()
scanf("%d%d",&n,&m);
T.init(n);
rep(i,1,m)
int u,v;scanf("%d%d",&u,&v);
deg[u][v]++,deg[v][u]++;
T.add(u,v);
int ans=T.cal();
if(ans*2!=n) return puts("IMPOSSIBLE"),0;
rep(i,1,n) deg[i][T.mh[i]]--;
//return 0;
rep(i,1,n) if(!vis[i])
tp=0;
dfs(i);
for(int j=0;j<tp;j++)
pre[que[j]]=que[(j+1)%tp];
rep(i,1,n)
if(i<T.mh[i])
printf("%d %d %d %d\\n",pre[i],i,T.mh[i],pre[T.mh[i]]);
return 0;
以上是关于2021上海L Three,Three,Three(一般图匹配)的主要内容,如果未能解决你的问题,请参考以下文章
three.js?????????????????????????????????
使用 FBXLoader 加载的相交对象——Three.js