1. 程式人生 > 其它 >ICPC Mid-Central USA Region 2019 題解

ICPC Mid-Central USA Region 2019 題解

隊友牛逼!帶我超神!蒟蒻的我還是一點一點的整理題吧...

Dragon Ball I

這個題算是比較裸的題目吧....學過圖論的大概都知道應該怎麼做。題目要求找到七個龍珠的最小距離。很明顯就是7個龍珠先後去的排列,然後用dijkstra預處理出來每個龍珠到所有其他的點的最短距離啊。最後dfs暴力列舉排列統計答案就行。這裡有一些小的細節問題題目中最大的距離為2e9,所以0x3f可能有點不夠,還真是細節決定成敗啊,不虧我Wrong了一發!

//不等,不問,不猶豫,不回頭.
#include<bits/stdc++.h>
#define _ 0
#define ls p<<1
#define db double
#define rs p<<1|1
#define P 1000000007
#define ll long long
#define INF 1000000000
#define get(x) x=read()
#define PLI pair<ll,int>
#define PII pair<int,int>
#define ull unsigned long long
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(x,y,z) for(int x=y;x<=z;++x)
#define fep(x,y,z) for(int x=y;x>=z;--x)
#define go(x) for(int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
using namespace std;
const int N=200010;
int n,m,link[N],id[10],tot,vis[N],d[10][N];
struct bian{ll y,v,next;}a[N<<1]; 
ll ans=1e18;
priority_queue<pair<ll,int> >q;

inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*ff;
}

inline void add(int x,int y,int v)
{
	a[++tot].y=y;a[tot].v=v;a[tot].next=link[x];link[x]=tot; 
}

inline void dijkstra(int s)
{
	rep(i,1,n) d[s][i]=2e9;
	memset(vis,0,sizeof(vis));
	d[s][id[s]]=0;
	q.push({0,id[s]});
	while(q.size())
	{
		int x=q.top().second;q.pop();
		if(vis[x]) continue;
		vis[x]=1;
		for(int i=link[x];i;i=a[i].next)
		{
			int y=a[i].y;
			if(d[s][y]>d[s][x]+a[i].v)
			{
				d[s][y]=d[s][x]+a[i].v;
				q.push({-d[s][y],y});
			}
		}
	}
}

inline void dfs(int now,int cnt,ll s)
{
	if(cnt==7) 
	{
		ans=min(ans,s);
		return;
	}
	rep(i,1,7) 
	{
		if(!vis[i])
		{
			vis[i]=1;
			dfs(i,cnt+1,s+d[now][id[i]]);
			vis[i]=0;
		}
	}
}

int main()
{
    //freopen("1.in","r",stdin);
	get(n);get(m);
	rep(i,1,m)
	{
		int get(x),get(y),get(v);
		add(x,y,v);add(y,x,v);
	}
	id[0]=1;
	rep(i,1,7) get(id[i]);
	rep(i,0,7) dijkstra(i);
	rep(i,1,7)
	{
		if(d[0][id[i]]==2e9) 
		{
			puts("-1");
			return 0;
		}
	}
	memset(vis,0,sizeof(vis));
	dfs(0,0,0);
	putl(ans);
    return (0^_^0);
}
//以吾之血,鑄吾最後的亡魂.