Graph

Posted last-diary

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Graph相关的知识,希望对你有一定的参考价值。

\(Graph\)

技术图片

首先,看到最大值最小一定要二分,然后怎样判断呢??

本来想在最短路上进行判断,自己把自己给\(Hash\)掉了,然后因为以前做过一道题目用的最小生成树,所以用最小生成树试了一下,发现可以过大样例。

具体证明也不会……

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<vector>
#define ll long long
using namespace std;
vector<ll>v;
const int N=8e3,M=2e5+100;
struct info
    int s,e;
    ll v;
id[M];
struct edge
    int s,e;
    ll v;
    int net;
ed[N<<1];
int n,m,k,tot;
int head[N],f[N],deep[N];
bool mark[N];
inline int getf(int x)

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

inline bool cmp(info a,info b)

    return a.v<b.v;

inline void add(int s,int e,ll v)

    ed[++tot]=(edge)s,e,v,head[s];
    head[s]=tot;
    return ;

inline void work()

    for (int i=1;i<=n;i++) f[i]=i;
    int num=0;
    for (int i=1;i<=m;i++)
    
        int a=getf(id[i].s),b=getf(id[i].e);
        if (a!=b)
        
            f[a]=b;
            int s=id[i].s,e=id[i].e;
            ll v=id[i].v;
            add(s,e,v);add(e,s,v);
            num++;
            if (num==n-1) break;
        
    
    return ;

inline void up(int x)

    if (x==n) return ;
    for (int i=head[x];i;i=ed[i].net)
    if (deep[ed[i].e]<deep[x])
    
        v.push_back(ed[i].v);
        up(ed[i].e);
    
    return ;

inline bool check(ll mid)

    ll now=0,num=0;
    for (int i=0;i<(int)v.size();i++)
    
        if (v[i]>mid) return 0;
        if (now+v[i]>mid)
        
            now=0;
            num++;
            if (num>k) return 0;
        
        now+=v[i];
    
    return 1;

inline void dfs(int x,int fa)

    deep[x]=deep[fa]+1;
    for (int i=head[x];i;i=ed[i].net)
    if (ed[i].e!=fa)
    dfs(ed[i].e,x);
    return ;

int main()

    scanf("%d%d%d",&n,&m,&k);
    if (m==0)
    
        printf("-1\n");
        return 0;
    
    ll sum=0;
    for (int i=1;i<=m;i++)
    
        int s,e;
        ll v;
        scanf("%d%d%lld",&s,&e,&v);
        id[i]=(info)s,e,v;
        sum+=v;
    
    sort(id+1,id+m+1,cmp);
    work();
    dfs(n,0);
    up(1);
    ll l=0,r=sum,mid=(l+r)>>1,ans;
    while (l<=r)
    
        if (check(mid))
        
            r=mid-1;
            ans=mid;
        
        else l=mid+1;
        mid=(l+r)>>1;
    
    printf("%lld\n",ans);
    return 0;

\(PS\):暴力转树根真好用。

以上是关于Graph的主要内容,如果未能解决你的问题,请参考以下文章

实验三

实验三

实验三:类和对象

图的顺序存储 湖南大学

实验4

《漫画算法2》源码整理-2 图算法