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
",dis[oo[i].y]+oo[i].w,dis[oo[i].y]);
}
printf("Case #%d: %d
",_,minn==inf?0:minn);
}
return 0;
}