当前位置:编程学习 > C/C++ >>

周赛 HDU 2874 HDU 2586 LCA

因为涉及到算法,所以就不把全部题目放到一个文章里了,方便以后找相关算法的时候查看。

HDU 2874

题意:给定一些点和边,询问两点之间是否连通,若连通,输出最短距离。

思路:离线tarjan算法,与其他裸题的区别就是要判是否在一棵树上。


[cpp] 
#include <iostream>  
#include <cstdio>  
#include <algorithm>  
#include <string>  
#include <cmath>  
#include <cstring>  
#include <queue>  
#include <set>  
#include <vector>  
#include <stack>  
#include <map>  
#include <iomanip>  
#define PI acos(-1.0)  
#define Max 100005  
#define inf 1<<28  
#define LL(x) (x<<1)  
#define RR(x) (x<<1|1)  
#define FOR(i,s,t) for(int i=(s);i<=(t);++i)  
#define ll long long  
#define mem(a,b) memset(a,b,sizeof(a))  
#define mp(a,b) make_pair(a,b)  
#define PII pair<int,int>  
using namespace std; 
 
struct kdq 

    int e,l,next ; 
} ed[Max] ,ee[2000005] ; 
int head1[Max] ; 
int nume = 0 ; 
int head[Max] ; 
int vis[Max] ; 
int num ; 
int dis[Max] ; 
int f[Max] ; 
int ans[Max * 10] ; 
 
void add(int s ,int e, int l) 

    ed[num].e = e ; 
    ed[num].l = l ; 
    ed[num].next = head[s] ; 
    head[s] = num ++ ; 

void adde(int s,int e,int l ) 

    ee[nume].e = e ; 
    ee[nume].next = head1[s] ; 
    ee[nume].l = l ; 
    head1[s] = nume ++ ; 

int aaa ; 
void init(int n ) 

    mem(head,-1); 
    mem(head1 ,-1) ; 
    nume = 0 ; 
    mem(vis,0) ; 
    num = 0 ; 
    mem(dis,0) ; 
    for (int i = 0 ; i <= n; i++)f[i] = i ; 
    mem(ans,0) ; 

 
int find(int x ) 

    return x == f[x] ? x :f[x] = find(f[x]) ; 

int nnn ; 
void dfs(int now,int pre,int l) 

    //cout <<nnn<<endl;  
    dis[now] = dis[pre] + l ; 
    for (int i = head[now] ; i != -1 ; i = ed[i].next ) 
    { 
        int e = ed[i].e ; 
        int l = ed[i].l ; 
        if(e == pre)continue; 
        dfs(e,now,l) ; 
        f[e] = now ; 
    } 
    vis[now] = nnn ; 
   // cout <<vis[now]<<endl;  
    for (int i = head1[now] ; i != -1 ;i = ee[i].next ) 
    { 
        int e = ee[i].e; 
 
        if(vis[e]) 
        { 
            //cout <<vis[e]<<endl;  
            if(find(e) == aaa||vis[e] == nnn)//判断是否在这棵树上找到该点  
            ans[ee[i].l] = dis[e] + dis[now] - 2 * dis[find(e)] ; 
            else ans[ee[i].l] = -1 ; 
        } 
    } 

int main() 

    int  T ; 
    int n ,m , k ; 
    while(scanf("%d%d%d",&n,&m,&k) != EOF) 
    { 
        init(n) ; 
        for (int i = 0 ; i < m ; i ++) 
        { 
            int a , b , c ; 
            scanf("%d%d%d",&a,&b,&c) ; 
            add(a,b,c) ; 
            add(b,a,c) ; 
        } 
        for (int i = 0 ; i < k ; i ++) 
        { 
            int a ,b ; 
            scanf("%d%d",&a,&b); 
            adde(a,b,i); 
            adde(b,a,i) ; 
 
        } 
       nnn = 1 ; 
       for (int i = 1 ;i <= n ;i ++) 
       { 
           if(!vis[i]) 
           { 
               aaa = i ; 
               nnn ++ ; 
               dfs(i,0,0) ; 
 
           } 
       } 
        for (int i = 0 ; i < k ; i ++) 
            if(ans[i] == -1 ) 
                puts("Not connected"); 
            else 
                printf("%d\n",ans[i]) ; 
    } 
 
    return 0; 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 100005
#define inf 1<<28补充:软件开发 , C++ ,

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,