给一个图,某些点需要单独以某一种颜色的线连接到1点,问如何安排能够使得整个图颜色最多的一条路颜色最少。
显然,二分枚举然后加以颜色其实就是流量了,相当于对每条边限定一个当前二分的流量值,判断能否满流即可。
召唤代码君:
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 555
#define maxm 333333
using namespace std; const int inf=~0U>>;
int to[maxm],next[maxm],c[maxm],first[maxm],edge;
int tag[maxn],d[maxn],TAG=;
int Q[maxn],bot,top;
bool can[maxn];
int n,m,k,T,h,s,t,house,ans,boder; void addedge(int U,int V)
{
edge++;
to[edge]=V,c[edge]=,next[edge]=first[U],first[U]=edge;
edge++;
to[edge]=U,c[edge]=,next[edge]=first[V],first[V]=edge;
} void _input()
{
scanf("%d%d%d",&n,&m,&k);
edge=-;
for (int i=; i<=n; i++) first[i]=-;
s=,t=,house=k;
while (k--)
{
scanf("%d",&h);
addedge(h,t);
}
boder=edge;
while (m--)
{
scanf("%d%d",&k,&h);
addedge(k,h);
}
} bool bfs()
{
Q[bot=top=]=t,d[t]=,can[t]=false,tag[t]=++TAG;
while(bot<=top)
{
int cur=Q[bot++];
for (int i=first[cur]; i!=-; i=next[i])
{
if (c[i^]> && tag[to[i]]!=TAG)
{
tag[to[i]]=TAG,Q[++top]=to[i];
d[to[i]]=d[cur]+,can[to[i]]=false;
if (to[i]==s) return true;
}
}
}
return false;
} int dfs(int cur,int num)
{
if (cur==t) return num;
int tmp=num,k;
for (int i=first[cur]; i!=-; i=next[i])
if (c[i]> && d[to[i]]==d[cur]- && tag[to[i]]==TAG && !can[to[i]])
{
k=dfs(to[i],min(num,c[i]));
if (k) num-=k,c[i]-=k,c[i^]+=k;
if (num==) break;
}
if (num) can[cur]=true;
return tmp-num;
} bool check(int x)
{
for (int i=; i<=boder; i++) c[i]=;
for (int i=boder+; i<=edge; i++) c[i]=x;
for ( ans=; bfs(); ) ans+=dfs(s,inf);
return ans>=house;
} int main()
{
scanf("%d",&T);
while (T--)
{
_input();
int l=,r=n,mid;
while (l<r)
{
mid=(l+r)>>;
if (check(mid)) r=mid;
else l=mid+;
}
printf("%d\n",l);
}
return ;
}