[補題記錄]CCPC 2016-2017, Finals-G - Pandaland Gym - 101206G
阿新 • • 發佈:2020-08-16
G - Pandaland Gym - 101206G
題意:
有一些無向邊,還有一些邊權,問能形成的權值最小的環的權值是多少
題解:
去列舉每一條邊跑兩個頂點除了這條邊的dijkstra 可以卡過
#include<bits/stdc++.h> using namespace std; #define ll long long #define lowbit(a) ((a) & -(a)) #define clean(a, b) memset(a, b, sizeof(a)) const int mod = 998244353; const int inf = 0x3f3f3f3f; const int maxn = 2e5 + 9; typedef pair<int,int>P; int _; //======================================================================== map<P,int>mp; struct node { int x,y,w; }oo[10009]; struct edge { int to,next,cost; }e[10009]; int top,head[10009],dis[10009],vis[10009],minn; void init() { memset(head,-1,sizeof(head)); top=0; } void add(int u,int v,int c) { e[top].to=v; e[top].cost=c; e[top].next=head[u]; head[u]=top++; } void dijkstra(int s,int t,int ww) //起點 終點 被選擇的那條邊的權值 { clean(dis,inf); clean(vis,0); dis[s]=0; priority_queue<P,vector<P>,greater<P> >q; q.push(P(0,s)); while(!q.empty()) { P now=q.top(); q.pop(); if(now.first+ww>minn) break; //優化--如果不滿足條件及時退出 if(vis[now.second]) continue; vis[now.second]=1; for(int i=head[now.second];i!=-1;i=e[i].next) { int ttt=e[i].to; int www=e[i].cost; if(now.second==s&&ttt==t||now.second==t&&ttt==s) continue; //不能是已經選擇的那條路 if(!vis[ttt]&&dis[now.second]+www<dis[ttt]) { dis[ttt]=dis[now.second]+www; q.push(P(dis[ttt],ttt)); } } } } //======================================================================== int main() { int T; scanf("%d",&T); for(_=1;_<=T;_++) { init(); mp.clear(); int m,x1,x2,y1,y2,ww,cnt=1; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&ww); //給的是點 那把這些點轉換成編號,就可以用鏈式前向星存了 int num1,num2; if(mp[P(x1,y1)]) num1=mp[P(x1,y1)]; //mp[]離散一下 else mp[P(x1,y1)]=cnt,num1=cnt++; if(mp[P(x2,y2)]) num2=mp[P(x2,y2)]; else mp[P(x2,y2)]=cnt,num2=cnt++; add(num1,num2,ww); //重新建個圖 add(num2,num1,ww); oo[i].x=num1,oo[i].y=num2,oo[i].w=ww; } minn=inf; for(int i=1;i<=m;i++) { dijkstra(oo[i].x,oo[i].y,oo[i].w); minn=min(minn,dis[oo[i].y]+oo[i].w); // printf("%d %d \n",dis[oo[i].y]+oo[i].w,dis[oo[i].y]); } printf("Case #%d: %d\n",_,minn==inf?0:minn); } return 0; }