P2941 [USACO09FEB] Surround the Islands S

 

>>>可以从任何一个顶点开始装篱笆,也可以从任何一个顶点坐船到另一个岛的某个顶点上,从这个顶点开始把该岛屿的篱笆全都装好,然后马上坐船原路返回 + 岛内不花费

-》从一节点反复出发 遍历 路径最小值

>>>Tarjan缩点+枚举边最小值,强连通分量 +Ans最后要乘二

:::非全局变量 初始化

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------debug\n");
using namespace std;
const int maxn=5e2+10;
const ll inf=0x3f3f3f3f;

int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
int dfn[maxn],low[maxn],dfstm,st[maxn],top,co[maxn],col;
int d[maxn][maxn],n;
ll ans=inf;

void add(int u,int v){
    to[++tot]=v,nxt[tot]=head[u],head[u]=tot;
}
void tarjan(int u)
{
    dfn[u]=low[u]=dfstm++; st[++top]=u;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(dfn[v]==0){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(co[v]==0) low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        co[u]=++col;
        while(st[top]!=u){
            co[st[top]]=col;
            top--;
        }
        top--;
    }
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    memset(d,inf,sizeof(d));
    
    cin>>n;
    for(int i=1;i<=n;i++){
        int u,v; cin>>u>>v;
        add(u,v),add(v,u);
    }
    
    for(int i=1;i<=n;i++) if(dfn[i]==0) tarjan(i);
    
    for(int i=1;i<=n;i++){
    //    ll tmp;
        for(int j=1;j<=n;j++){
            int dis;cin>>dis;
            d[co[i]][co[j]]=min(d[co[i]][co[j]],dis);
            //tmp+=d[co[i]][co[j]];
        }
        //tmp=min(tmp,ans);
    }
    for(int i=1;i<=col;i++){
        ll tmp=0;//·ÇÈ«¾Ö±äÁ¿ ³õʼ»¯
        for(int j=1;j<=col;j++){
            if(i==j) continue;
            tmp+=d[i][j];
        }
        
        ans=min(tmp,ans);
        tmp=0;
    }
    cout<<(ans*2)<<'\n';
     
    return 0;
}
View Code

 

 
 
 
posted @ 2023-08-13 10:18  JMXZ  阅读(11)  评论(0)    收藏  举报