Codeforces 196 E. Opening Portals

Problem E. Opening Portals

首先根据传送门的性质,如果所有点都是传送门的话那么结果就是该图的最小生成树。

对于只有其中 k 个结点是传送门的图,只要在原算法的基础上稍作修改即可。

具体,对每个点求出 P[i] 和 D[i] 。(表示距离这个点最近的传送门和其距离。。。

之后对每条边,再根据 D[x] + D[y] + w 作为关键字跑最小生成树。。

以上分别用一次多源 spfa(),和稍作修改的 Kruskal() 即可。

E. Opening Portals

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Pavel plays a famous computer game. A player is responsible for a whole country and he can travel there freely, complete quests and earn experience.

This country has n cities connected by m bidirectional
roads of different lengths so that it is possible to get from any city to any other one. There are portals in k of these cities. At the beginning of the
game all portals are closed. When a player visits a portal city, the portal opens. Strange as it is, one can teleport from an open portal to an open one. The teleportation takes no time and that enables the player to travel quickly between rather remote regions
of the country.

At the beginning of the game Pavel is in city number 1. He wants to open all portals as quickly as possible. How much time will he need for that?

Input

The first line contains two space-separated integers n and m (1?≤?n?≤?105, 0?≤?m?≤?105)
that show how many cities and roads are in the game.

Each of the next m lines contains the description of a road as three space-separated integers xiyiwi (1?≤?xi,?yi?≤?nxi?≠?yi, 1?≤?wi?≤?109)
— the numbers of the cities connected by the i-th road and the time needed to go from one city to the other one by this road. Any two cities are connected
by no more than one road. It is guaranteed that we can get from any city to any other one, moving along the roads of the country.

The next line contains integer k (1?≤?k?≤?n)
— the number of portals.

The next line contains k space-separated integers p1, p2,
..., pk — numbers
of the cities with installed portals. Each city has no more than one portal.

Output

Print a single number — the minimum time a player needs to open all portals.

Please, do not use the %lld specifier to read or write 64-bit integers in C++. It is preferred to use the cin, cout streams
or the %I64dspecifier.

Sample test(s)

input

3 3
1 2 1
1 3 1
2 3 1
3
1 2 3

output

2

input

4 3
1 2 1
2 3 5
2 4 10
3
2 3 4

output

16

input

4 3
1 2 1000000000
2 3 1000000000
3 4 1000000000
4
1 2 3 4

output

3000000000

Note

In the second sample the player has to come to city 2, open a portal there, then go to city 3,
open a portal there, teleport back to city 2and finally finish the journey in city 4.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int maxn=100100;
typedef long long int LL;

int n,m,c;

struct Edge
{
	int from,to,next;
	LL weight;
}edge[3*maxn];

int Adj[maxn],Size;
int p[maxn],cq[maxn];
LL dist[maxn];
bool inq[maxn];

void init()
{
	memset(Adj,-1,sizeof(Adj)); Size=0;
}

void Add_Edge(int u,int v,LL w)
{
	edge[Size].from=u;
	edge[Size].to=v;
	edge[Size].next=Adj[u];
	edge[Size].weight=w;
	Adj[u]=Size++;
}

bool spfa()
{
	memset(dist,63,sizeof(dist));
	memset(p,0,sizeof(p));
	memset(cq,0,sizeof(cq));
	memset(inq,false,sizeof(inq));
	int k=c;
	queue<int> q;
	for(int i=0;i<k;i++)
	{
		int x;
		scanf("%d",&x);
		dist[x]=0; p[x]=x;
		q.push(x); cq[x]=1; inq[x]=true;
	}
	while(!q.empty())
	{
		int u=q.front(); q.pop();
		for(int i=Adj[u];~i;i=edge[i].next)
		{
			int v=edge[i].to;
			if(dist[v]>dist[u]+edge[i].weight)
			{
				dist[v]=dist[u]+edge[i].weight;
				p[v]=p[u];
				if(!inq[v])
				{
					inq[v]=true;
					cq[v]++;
					if(cq[v]>=n) return false;
					q.push(v);
				}
			}
		}
		inq[u]=false;
	}
	return true;
}

struct BA
{
	int x,y;
	LL w;
}bian[3*maxn];

bool cmp(BA a,BA b)
{
	return a.w<b.w;
}

int fa[maxn];

int find(int x)
{
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}

int main()
{
	scanf("%d%d",&n,&m);
	init();
	for(int i=0;i<m;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		Add_Edge(a,b,c);
		Add_Edge(b,a,c);
	}
	scanf("%d",&c);
	spfa();
	for(int i=0;i<=n+10;i++) fa[i]=i;
	for(int i=0;i<Size;i++)
	{
		int u=edge[i].from,v=edge[i].to;
		bian[i].x=p[u],bian[i].y=p[v];
		bian[i].w=dist[u]+dist[v]+edge[i].weight;
	}
	sort(bian,bian+Size,cmp);
	int cnt=1;
	LL ans=dist[1];
	for(int i=0;i<Size&&cnt<c;i++)
	{
		int u=bian[i].x,v=bian[i].y;
		LL w=bian[i].w;
		if(u==v) continue;
		int U=find(u),V=find(v);
		if(U==V) continue;
		else
		{
			ans+=w;
			fa[U]=V;
			cnt++;
		}
		if(cnt>=c) break;
	}
	cout<<ans<<endl;
	return 0;
}

Codeforces 196 E. Opening Portals

时间: 2024-10-11 07:25:08

Codeforces 196 E. Opening Portals的相关文章

[Codeforces #196] Tutorial

Link: Codeforces #196 传送门 A: 枚举 #include <bits/stdc++.h> using namespace std; #define X first #define Y second typedef long long ll; typedef pair<int,int> P; const int MAXN=1e5+10; int n,m,dat[MAXN],res=1<<30; int main() { scanf("%d

【做题】CF196E. Opening Portals 排除无用边&amp;最小生成树

题意:给出一个有\(n\)个结点,\(m\)条边的连通无向图,边有边权,等于经过这条边所需的时间.有\(k\)个点设有传送门.一开始,所有传送门关闭.你从\(1\)号点出发,每当你到达一个有传送门的点,那个传送门就会永久开启.你可以从一个开启的传送门花费\(0\)时间到达另一个开启的传送门.求开启所有传送门所需的最小时间. \(n,m \leq 10^5\) 首先,简化一下题目.当到达第一个传送门点后,因为已经过传送门可以互相传送,所以剩下的时间就是所有传送门点两两之间连权值等于最短路的边建成的

Codeforces Round #196 (Div. 2) B. Routine Problem

screen 尺寸为a:b video 尺寸为 c:d 如果a == c 则 面积比为 cd/ab=ad/cb (ad < cb) 如果b == d 则 面积比为 cd/ab=cb/ad  (cb < ad) 如果不相等时 如果a/b > c/d,则ad/bd > cb/db 则(ad > cb) screen尺寸可为 ad:bd, video的尺寸可为 cb:db 面积比为:cb*db/ad*bd = cb/ad (ad > cb) 如果a/b < c/d,则a

Codeforces Round #196 (Div. 2) A. Puzzles 水题

A. Puzzles Time Limit: 2 Sec  Memory Limit: 60 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5373 Description The end of the school year is near and Ms. Manana, the teacher, will soon have to say goodbye to a yet another class. S

Codeforces Round #608 (Div. 2) - D. Portals(贪心)

题意:你起初有一支军队,有$k$个士兵,现在有$n$座城堡,你若想占领第$i$座城堡,至少得有$a[i]$个士兵才能占领$($占领后士兵不会减少$)$,占领了第$i$座城堡后,你将得到$b[i]$个士兵,然后你有两种方式防御你占领的城堡: 在你占领第$i$个城堡后留下一个士兵防御第$i$个城堡 有$m$个传送门,能从$u_{i}$传送到$v_{i}(u_{i}>v_{i})$,你可以在占领完第$u_{i}$座城堡后再派一个士兵去防御第$v_{i}$个城堡 如果你防御了第$i$座城堡,你能得到$c

Codeforces Round #408 (Div. 2) B

Description Zane the wizard is going to perform a magic show shuffling the cups. There are n cups, numbered from 1 to n, placed along the x-axis on a table that has m holes on it. More precisely, cup i is on the table at the position x?=?i. The probl

Codeforces Round#413 Problem A - C

[写在前面感(乱)叹(七)人(八)生(糟)的话] 本想借此机会一口气玩到蓝名,结果,A题写炸(少判了一种情况),C题写炸(辜负了我5分钟狂敲出来的线段树),结果又掉Rating...内心好绝望... Problem#A Carrot Cakes vjudge链接[here] (偷个懒,cf链接就不给了) 题目大意是说,烤面包,给出一段时间内可以考的面包数,建第二个炉子的时间,需要达到的面包数,问建炉子是否合理. 玄学 & 智商题,可能是因为我智商不够,所以在我决定休息的时候被hank掉了...

Codeforces Round #245 (Div. 1)——Tricky Function

l and dished out an assist in the Blackhawks' 5-3 win over the Nashville Predators.Shaw said just playing with the Blackhawks was enough motivation for him."Positive, I'm playing in the NHL," Shaw said after Sunday's win. "What can't you be

CodeForces 337A Puzzles

Puzzles Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 337A64-bit integer IO format: %I64d      Java class name: (Any) The end of the school year is near and Ms. Manana, the teacher, will soon have t