题意:给定一张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 爬取网页内的代理服务器列表(需调整优化)

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2017-08-30 20:38:23 # @Author : EnderZhou (z ...

  2. PTA 7-20 表达式转换

    转自:https://www.cnblogs.com/yuxiaoba/p/8399934.html 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.日常使用的算术表达式是采用中缀表示法,即二元 ...

  3. bi的tableau

    参考: 官网: https://help.tableau.com/current/server-linux/zh-cn/get_started_server.htm 可视化分析最佳做法: 实用指南 h ...

  4. noip2011day2-观光公交

    题目描述 风景迷人的小城 \(Y\) 市,拥有 $n $个美丽的景点. 由于慕名而来的游客越来越多,\(Y\) 市特 意安排了一辆观光公交车,为游客提供更便捷的交通服务. 观光公交车在第 \(0\) ...

  5. scrapy之360图片爬取

    #今日目标 **scrapy之360图片爬取** 今天要爬取的是360美女图片,首先分析页面得知网页是动态加载,故需要先找到网页链接规律, 然后调用ImagesPipeline类实现图片爬取 *代码实 ...

  6. Electric Charges CodeForces - 623C (二分答案)

    大意: 平面上n个点每个点坐标为(x,0)或(0,y), 求任意两点距离平方最大值的最小值. 二分答案, 转化为判定最大值是否<=e, 按$x$排序后, 因为固定左端点, $y$绝对值的最大值是 ...

  7. Linux 问题集

    解决E: Encountered a section with no Package: header错误 我的ubuntu机器上出现下面这个错误. Reading package lists... E ...

  8. 简单Delphi程序设计

  9. 安装最新版本的kubernets(+安装插件dashboard)

    一.安装docker // 安装系统工具: sudo yum install -y yum-utils device-mapper-persistent-data lvm2 // 添加docker y ...

  10. 最简单的Android项目(含有资源文件)

    上次的项目没有使用资源文件,打包出的apk安装后是系统默认图标,程序标题也是包名加类名. 添加资源需要对编译的命令做一点调整. 首先在项目根目录新建res和assets目录,在res内新建drawab ...