ICPC Mid-Central USA Region 2019 題解
阿新 • • 發佈:2021-08-19
隊友牛逼!帶我超神!蒟蒻的我還是一點一點的整理題吧...
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); } //以吾之血,鑄吾最後的亡魂.