1. 程式人生 > 實用技巧 >[補題記錄]CCPC 2016-2017, Finals-G - Pandaland Gym - 101206G

[補題記錄]CCPC 2016-2017, Finals-G - Pandaland Gym - 101206G

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;
}