题意:给定一张n点n边无重边自环的无向图,刚开始每条边都没有被选择,每条边上有一个颜色集合,必须从中选择一种

有K个工人,每个工人有颜色a[i],需要把工人分配到与其颜色相同的边上

问是否能有一种使得n个点完全联通的方案,如果有则输出

n,K<=2000

思路:考虑n-1条边的树的弱化版,显然每条边都应该被选择,用颜色和边建图跑最大流即可

n点n边的基环树的情况下需要把环抠出来,设环的大小为size,两个端点至少有一个在环中的为A集合,其余为B集合

显然B集合中所有的边都需要被选取,A集合中至多只能选择size-1条

可以另外加源或者汇限制A集合的流量,也可以先加入B集合中的所有边,先跑最大流,判断是否小于n-size,因为A集合至多只有size-1的流量

两种方法都试过,都很快

我猜题解里写的应该就是用最大流跑的匹配,没听说过有能跑这个多重匹配的新算法

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,ll>P;
#define N 200010
#define M 1000000
#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1
#define fors(i) for(auto i:e[x]) if(i!=p) const int MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int dx[]={-,,,};
int dy[]={,,-,}; int head[N],vet[N],len[N],nxt[N],inq[N],inc[N],a[N],
flag[N],vis[N],stk[N],dis[N],p[N],c[N],match[N],
tot,top,s,S,T,T1; VI b[N],co[N]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} ll readll()
{
ll v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void add(int a,int b)
{
nxt[++tot]=head[a];
vet[tot]=b;
head[a]=tot;
} void Add(int a,int b,int c)
{
nxt[++tot]=head[a];
vet[tot]=b;
len[tot]=c;
head[a]=tot; nxt[++tot]=head[b];
vet[tot]=a;
len[tot]=;
head[b]=tot;
} void findc(int u,int fa)
{
stk[++top]=u;
inq[u]=vis[u]=;
int e=head[u];
while(e)
{
int v=vet[e];
if(!vis[v]) findc(v,u);
else if(v!=fa&&inq[v])
{
int s=,t=top;
while()
{
t--;
s++;
if(stk[t]==v) break;
}
if(s>=)
{
t=top;
while()
{
inc[stk[t]]=;
t--;
if(stk[t]==v){inc[v]=; break;}
} }
}
e=nxt[e];
}
inq[stk[top]]=;
top--;
} int bfs()
{
queue<int> q;
rep(i,,s) dis[i]=-;
q.push(S),dis[S]=;
while(!q.empty())
{
int u=q.front();
q.pop();
int e=head[u];
while(e)
{
int v=vet[e];
if(len[e]&&dis[v]==-)
{
dis[v]=dis[u]+;
q.push(v);
}
e=nxt[e];
}
}
return dis[T]!=-;
} int dfs(int u,int aug)
{
if(u==T) return aug;
int e=head[u],val=,flow=;
while(e)
{
int v=vet[e];
if(len[e]&&dis[v]==dis[u]+)
{
int t=dfs(v,min(len[e],aug));
if(!t)
{
e=nxt[e];
continue;
}
flow+=t;
aug-=t;
len[e]-=t;
len[e^]+=t;
if(!aug) break;
}
e=nxt[e];
}
if(!flow) dis[u]=-;
return flow;
} int main()
{
int n=read(),K=read();
int m=;
rep(i,,n)
{
p[i]=read();
int x=read();
while(x--)
{
int y=read();
b[i].pb(y);
c[++m]=y;
}
}
rep(i,,K)
{
a[i]=read();
c[++m]=a[i];
}
sort(c+,c+m+);
int k=unique(c+,c+m+)-c-;
rep(i,,n)
for(int j=;j<b[i].size();j++) b[i][j]=lower_bound(c+,c+k+,b[i][j])-c; rep(i,,k) co[i].clear();
rep(i,,K)
{
a[i]=lower_bound(c+,c+k+,a[i])-c;
co[a[i]].pb(i);
} tot=;
rep(i,,n)
{
add(i,p[i]);
add(p[i],i);
}
findc(,);
s=k+n,S=++s,T=++s;
rep(i,,s) head[i]=;
tot=;
int sz=;
rep(i,,k) Add(S,i,co[i].size());
rep(i,,n)
for(int j=;j<b[i].size();j++) Add(b[i][j],i+k,);
rep(i,,n)
if(inc[i]==||inc[p[i]]==) Add(i+k,T,);
else sz++;
int ans=;
while(bfs()) ans+=dfs(S,INF);
if(ans<(n--(sz-)))
{
printf("-1\n");
return ;
}
rep(i,,n)
if(inc[i]&&inc[p[i]]) Add(i+k,T,);
while(bfs()) ans+=dfs(S,INF);
if(ans<n-) printf("-1\n");
else
{
rep(i,,n) flag[i]=;
rep(i,,k)
{
int e=head[i],j=;
while(e)
{
int v=vet[e];
if(v>=k+&&v<=k+n&&flag[v-k]==&&!len[e])
{
j++;
if(j>(int)co[i].size()) break;
int t=co[i][j-];
match[t]=v-k;
flag[v-k]=;
}
e=nxt[e];
}
}
rep(i,,K) printf("%d %d\n",match[i],p[match[i]]);
} return ;
}

【CF1252L】Road Construction(基环树,最大流)的更多相关文章

  1. POJ3352 Road Construction (双连通分量)

    Road Construction Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Sub ...

  2. POJ P3352 Road Construction 解题报告

    P3352 Road Construction 描述 这几乎是夏季,这意味着它几乎是夏季施工时间!今年,负责岛屿热带岛屿天堂道路的优秀人士,希望修复和升级岛上各个旅游景点之间的各种道路. 道路本身也很 ...

  3. [POJ3352]Road Construction

    [POJ3352]Road Construction 试题描述 It's almost summer time, and that means that it's almost summer cons ...

  4. POJ3352 Road Construction(边双连通分量)

                                                                                                         ...

  5. poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

  6. POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)

    POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...

  7. 【BZOJ1791】【IOI2008】【基环树】island(status第一速度)

      1791: [Ioi2008]Island 岛屿  Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 908  Solved: 159 [Su ...

  8. POJ3352 Road Construction 双连通分量+缩点

    Road Construction Description It's almost summer time, and that means that it's almost summer constr ...

  9. 【Tarjan缩点】PO3352 Road Construction

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12532   Accepted: 630 ...

随机推荐

  1. python 并发编程 io模型 目录

    python 并发编程 IO模型介绍 python 并发编程 socket 服务端 客户端 阻塞io行为 python 并发编程 阻塞IO模型 python 并发编程 非阻塞IO模型 python 并 ...

  2. 洛谷 P2384 最短路 题解

    题面 这道题需要用到一个神奇的知识点:log(n*m)=log(n)+log(m): 所以对所有边权取个log,然后算log的最短路的同时维护乘积即可 #include <bits/stdc++ ...

  3. 树型DP入门

    题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚 ...

  4. selenium获取微博用户粉丝数

    selenum的安装 selenium文档 获取微博用户粉丝数 from selenium import webdriver from time import sleep wd = webdriver ...

  5. ElasticSearch基础知识讲解

    第一节 ElasticSearch概述 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfull web接口.ElasticSea ...

  6. TCP的.cc文件代码解释(中文)

    #ifndef lint static const char rcsid[] =     "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/tcp/tcp ...

  7. (转) Delete/Truncate删除,释放表空间、降低高水位线、resize释放磁盘空间相关优化

    硬盘空间不足,打算删除数据库中的多余数据,但删除数据后,硬盘硬盘空间不能释放.[delete后用:alter table table_name move    truncate后用:alter tab ...

  8. GlobalLock锁定一个全局内存对象

    GlobalLock BAIPro

  9. selenium-java爬虫实现

    推荐的网站学习网站 1.官方文档 http://www.seleniumhq.org/docs/ 2.selenium多线程 http://www.cnblogs.com/dingmy/p/34380 ...

  10. 【30分钟学完】canvas动画|游戏基础(extra1):颜色那些事

    前言 本篇主要讲解关于计算机颜色系统的概念,后续结合一些canvas的应用.因为是"你不知道也没关系"的边缘知识,所以作为本系列教程的扩展,没有兴趣的同学可以跳过. 开始我们万紫千 ...