首页 > 其他分享 >[ABC245G] Foreign Friends

[ABC245G] Foreign Friends

时间:2023-01-09 22:57:05浏览次数:42  
标签:Person int Friends Foreign leq cost popular ABC245G friends

Problem Statement

There are $N$ people and $K$ nations, labeled as Person $1$, Person $2$, $\ldots$, Person $N$ and Nation $1$, Nation $2$, $\ldots$, Nation $K$, respectively.
Each person belongs to exactly one nation: Person $i$ belongs to Nation $A_i$. Additionally, there are $L$ popular people among them: Person $B_1$, Person $B_2$, $\ldots$, Person $B_L$ are popular. Initially, no two of the $N$ people are friends.

For $M$ pairs of people, Takahashi, a God, can make them friends by paying a certain cost: for each $1\leq i\leq M$, he can pay the cost of $C_i$ to make Person $U_i$ and Person $V_i$ friends.

Now, for each $1\leq i\leq N$, solve the following problem.

Can Takahashi make Person $i$ an indirect friend of a popular person belonging to a nation different from that of Person $i$? If he can do so, find the minimum total cost needed. Here, Person $s$ is said to be an indirect friend of Person $t$ when there exists a non-negative integer $n$ and a sequence of people $(u_0, u_1, \ldots, u_n)$ such that $u_0=s$, $u_n=t$, and Person $u_i$ and Person $u_{i+1}$ are friends for each $0\leq i < n$.

Constraints

  • $2 \leq N \leq 10^5$
  • $1 \leq M \leq 10^5$
  • $1 \leq K \leq 10^5$
  • $1 \leq L \leq N$
  • $1 \leq A_i \leq K$
  • $1 \leq B_1<B_2<\cdots<B_L\leq N$
  • $1\leq C_i\leq 10^9$
  • $1\leq U_i<V_i\leq N$
  • $(U_i, V_i)\neq (U_j,V_j)$ if $i \neq j$.
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

$N$ $M$ $K$ $L$
$A_1$ $A_2$ $\cdots$ $A_N$
$B_1$ $B_2$ $\cdots$ $B_L$
$U_1$ $V_1$ $C_1$
$U_2$ $V_2$ $C_2$
$\vdots$
$U_M$ $V_M$ $C_M$

Output

Let $X_i$ defined as follows: $X_i$ is $-1$ if it is impossible to make Person $i$ an indirect friend of a popular person belonging to a nation different from that of Person $i$; otherwise, $X_i$ is the minimum total cost needed to do so. Print $X_1, X_2, \ldots, X_N$ in one line, with spaces in between.


Sample Input 1

4 4 2 2
1 1 2 2
2 3
1 2 15
2 3 30
3 4 40
1 4 10

Sample Output 1

45 30 30 25

Person $1$, $2$, $3$, $4$ belong to Nation $1$, $1$, $2$, $2$, respectively, and there are two popular people: Person $2$ and $3$. Here,

  • For Person $1$, the only popular person belonging to a different nation is Person $3$. To make them indirect friends with the minimum cost, we should pay the cost of $15$ to make Person $1$ and $2$ friends and pay $30$ to make Person $2$ and $3$ friends, for a total of $15+30=45$.
  • For Person $2$, the only popular person belonging to a different nation is Person $3$. The minimum cost is achieved by making Person $2$ and $3$ friends by paying $30$.
  • For Person $3$, the only popular person belonging to a different nation is Person $2$. The minimum cost is achieved by making Person $2$ and $3$ friends by paying $30$.
  • For Person $4$, the only popular person belonging to a different nation is Person $2$. To make them indirect friends with the minimum cost, we should pay the cost of $15$ to make Person $1$ and $2$ friends and pay $10$ to make Person $1$ and $4$ friends, for a total of $15+10=25$.

Sample Input 2

3 1 3 1
1 2 3
1
1 2 1000000000

Sample Output 2

-1 1000000000 -1

Note that, for Person $1$, Person $1$ itself is indeed an indirect friend, but it does not belong to a different nation, so there is no popular person belonging to a different nation.

暴力怎么做?枚举每一种国籍 \(i\),考虑这个国籍的明星带给其他人的影响。建立一个虚拟节点,向每一个这个国籍的明星连一条0边。然后以 \(0\) 为起点跑一次 dijkstra,得到每一个点的最短路,而对于 \(a_i\ne a_j\) 的人,用当前跑出来的最短路更新其答案。复杂度 \(O(mk\log m)\)

为什么我们要枚举国籍?其实就只是为了保证 \(a_i\ne a_j\),这个作用有点废,考虑二进制优化,什么时候 \(a_i\ne a_j\) 呢?一定存在某一个二进制位不同。枚举每个二进制位,把虚拟节点向所有 \(a_i\) 的这个二进制位为 1 的节点连边,跑完之后,所有这一个二进制位为 0 的节点更新答案。复杂度将为 \(O(m \log^2m)\)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct edge{
	int v,nxt,w;
}e[N*3];
int hd[N],a[N],f[N],idx,u,v,w;
long long dis[N],ans[N];
void add_edge(int u,int v,int w)
{
	e[++idx]=(edge){v,hd[u],w};
	hd[u]=idx;
}
struct node{
	int v;
	long long w;
	bool operator<(const node&n)const{
		return w>n.w;
	}
};
int n,m,k,l;
priority_queue<node>q;
inline void dijkstra()
{
	memset(dis,0x7f,sizeof(dis));
	q.push((node){0,0});
	dis[0]=0;
	while(!q.empty())
	{
		v=q.top().v;
		if(dis[v]!=q.top().w)
		{
			q.pop();
			continue;
		}
		q.pop();
		for(int i=hd[v];i;i=e[i].nxt)
		{
			if(dis[v]+e[i].w<dis[e[i].v])
			{
				dis[e[i].v]=dis[v]+e[i].w;
				q.push((node){e[i].v,dis[e[i].v]});
			}
		}
	}
}
inline void calc(int i,int t)
{
	for(int j=1;j<=n;j++)
			if(((a[j]>>i&1)==t)&&f[j])
				add_edge(0,j,0);
	
	dijkstra();
	hd[0]=0,idx=m<<1;
	for(int j=1;j<=n;j++)
		if(t!=(a[j]>>i&1))
			ans[j]=min(ans[j],dis[j]);
}
int main()
{
	memset(ans,0x7f,sizeof(ans));
	scanf("%d%d%d%d",&n,&m,&k,&l);
	for(int i=1;i<=n;i++)
		scanf("%d",a+i);
	for(int i=1;i<=l;i++)
		scanf("%d",&u),f[u]=1;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&u,&v,&w);
		add_edge(u,v,w);
		add_edge(v,u,w);
	}
	for(int i=0;i<17;i++)
	{
		calc(i,0);
		calc(i,1);
	}
	for(int i=1;i<=n;i++)
		printf("%lld ",ans[i]>1e18? -1:ans[i]);
	return 0;
}

标签:Person,int,Friends,Foreign,leq,cost,popular,ABC245G,friends
From: https://www.cnblogs.com/mekoszc/p/17038758.html

相关文章