NOI2003 逃學的小孩

題目連接 https://www.luogu.com.cn/problem/P4408

分析

這好像很裸的樣子,題目說了一堆廢話,最後其實就是讓求三個點,使得\(AB+BC\)最小,感性的理解蒙一下,應該有一條邊是直徑,否則把任意一條邊換成直徑均可以使答案更優,而後就找直徑唄,找完直徑枚舉直徑兩端點到其餘點的距離,最後答案爲直徑長+\(max(min(dis1,dis2))\),好像就水過這道題了?
因爲它是個樹,因此根據某學長的理論,隨便跑均可以,我dfs忘記咋寫的了,想練一下spfa來,畢竟我那個不熟,但看了看時間太晚了就打了一個dij,沒想到真的過了。。。證實的話明天心情好再補吧ios

#include<iostream>
#include<queue>
#define ll long long 
using namespace std;
const int N=2e5+10;
struct Edge{
    int to,nxt;
    ll val;
}e[N<<1];
struct Node{
    int id;ll val;
    Node(){}
    Node(int a,ll b){id=a,val=b;}
    bool operator <(const Node&A)const {
        return val>A.val;
    }
};
int Head[N],len;
void Ins(int a,int b,ll c){
    e[++len].to=b;e[len].val=c;
    e[len].nxt=Head[a];Head[a]=len;
}
int n;bool inq[N];
ll dis1[N],dis2[N];
int dij(int s,ll dis[N]){
    for(int i=1;i<=n;i++){
        dis[i]=1e17;
        inq[i]=0;
    }
    dis[s]=0;inq[s]=1;
    priority_queue<Node> q;q.push(Node(s,0));
    while(!q.empty()){
        Node u=q.top();q.pop();inq[u.id]=0;
        for(int i=Head[u.id];i;i=e[i].nxt){
            int v=e[i].to;
            if(inq[v])continue;
            inq[v]=1;
            if(dis[v]>dis[u.id]+e[i].val){
                dis[v]=dis[u.id]+e[i].val;
                q.push(Node(v,dis[v]));
            }
        }
    }
    ll Max=0;int id=0;
    for(int i=1;i<=n;i++)
        if(dis[i]>Max)Max=dis[i],id=i;
    return id;
}
int main(){
    ios::sync_with_stdio(false);
    int m;
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int a,b;ll c;
        cin>>a>>b>>c;
        Ins(a,b,c);Ins(b,a,c);
    }
    int a=dij(1,dis1);
    int b=dij(a,dis2);
    dij(b,dis1);
    ll Max=0;
    for(int i=1;i<=n;i++)
        Max=max(Max,min(dis1[i],dis2[i]));
    cout<<dis2[b]+Max;
}

Tips:

你會發現我在函數裏寫的是手動賦值,爲啥不\(memset\)呢,這裏用\(memset\)的話會出問題,又可能要問了,以前跑最短路用沒出過問題啊,但這裏是不同的,這裏是對傳進來的一個數組進行復制,\(memset\)自己沒有問題,問題出在\(size of\)上,\(size of\)的處理時間的在編譯期,也就是說對於動態生成的數組大小是不能用\(sizeof\)來算出來的。由於若是傳到函數裏,數組會退化成指針,因而\(size of\)就返回了指針的大小,這顯然不是咱們想要的,解決問題的辦法有兩個。一是像我那樣,二是由於每次傳的\(dis\)數組大小同樣,直接寫\(size of dis1\),這樣編譯器就能夠肯定咱們\(size of\)的大小了。數組

相關文章
相關標籤/搜索