EC-final2018 L - Eventual … Journey Gym - 102056L(算贡献)

社会主义新天地 提交于 2019-12-10 04:30:57

LCR is really an incredible being.

Thinking so, sitting on the plane and looking at the sea, Rikka savours the fantastic journey. A fire never happened. It must be interesting to share it with her mates, and another travel is also fascinating.

But before all, home is the best.

She travels by the JR lines. There are n stations in total, and m public bidirectional railway lines are built among them. Each station belongs to either JR West or JR East. Both JR West and JR East have their own private railways connecting all stations owned by themselves.

Rikka has some through tickets and two types of special passes: ICOCA for JR West and Suica for JR East. She pays a through ticket each time and does one of the following:

Travel from one terminal to another via a public railway line.
Travel to any station which has the same owner as the current one, using one of her special passes. A pass can be used for multiple times.
Rikka wonders, for each start station, the sum of the minimal numbers of tickets she needs to pay to reach every possible one of the other stations.

Input
The first line contains two integers n,m (1≤n≤105,0≤m≤105), the numbers of stations and public railways.

The next line contains n integers Ai (Ai∈{0,1},i=1,2,…,n), separated by spaces, describing the owner of each station. Ai=0 if the station i belongs to JR west, and vice versa.

The following m lines describe all the public railways, each of which contains two integers u,v (1≤u,v≤n,u≠v), representing a bidirectional railway connecting u and v. It is guaranteed that no two public railways connect the same pair of stations, and Rikka is able to travel between every pair of stations. Notice that the private railways are not given directly in the input, and Rikka may have to use her passes rather than traveling only through the public railways.

Output
Output n integers in one line, separated by spaces. The i-th integer is ∑nj=1D(i,j) , where D(u,v) is the minimal number of tickets needed to travel from u to v.

Examples
Input
3 2
1 0 0
1 2
1 3
Output
2 2 2
Input
5 3
1 0 1 0 1
1 2
2 3
4 5
Output
5 5 5 6 5

题意:
一个无向图。每个点对应一个公司。
两种走路方式,每种方式走一步花一张票

  1. 直接走边
  2. 传送到和自己相同公司的点

设d(i,j)为i到j的最小票数。
求每个点的∑d(i,j)。

思路:
算贡献!!
忽略掉同一类型的点连接的边
直接连了边的和同一类型的点贡献都是1。
否则贡献为2.
但是特殊的是,两个不同类型的孤立点,贡献为3,我们这里没有考虑到,卡了超久。

#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 4e5 + 7;
int num[maxn];
int color[maxn];
int flag[maxn];

int main()
{
	int n,m;scanf("%d%d",&n,&m);
	int cnt = 0;//the number of 1
	for(int i = 1;i <= n;i++)
	{
		scanf("%d",&color[i]);
		if(color[i])cnt++;
	}
	for(int i = 1; i <= m;i++)
	{
		int x,y;scanf("%d%d",&x,&y);
		if(color[x] == color[y])continue;
		num[x]++,num[y]++;
		flag[x] = flag[y] = 1;
	}
	int dat0 = 0,dat1 = 0;
	for(int i = 1;i <= n;i++)
	{
		if(!flag[i] && color[i])
			dat1++;
		else if(!flag[i] && !color[i])
			dat0++;
	}

	for(int i = 1;i <= n;i++)
	{
		int ans = 0;
		if(color[i])
		{
			ans = cnt - 1;
			ans += num[i];
			if(num[i] == 0)
			{
				ans += (n - num[i] - cnt - dat0) * 2;
				ans += dat0 * 3;
			}
			else 
			{
				ans += (n - num[i] - cnt) * 2;
			}
		}
		else 
		{
			ans = n - cnt - 1;
			ans += num[i];
			if(num[i] == 0)
			{
				ans += (cnt - num[i] - dat1) * 2;
				ans += dat1 * 3;
			}  
			else 
			{
				ans += (cnt - num[i]) * 2;
			}
		}
		printf("%d ",ans);
	}
	printf("\n");
	return 0;
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!