51nod 1443 路径和树

来源:互联网 发布:sql语句like用法 编辑:程序博客网 时间:2024/06/06 01:43

题目链接

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443

思路

先求一次最短路,然后考虑最短路上的边作为树的边, 失了智,最大值爆int了。

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<string>#include<queue>#include<limits.h>#include<stack>#include<set>#include<map>#define ll long longusing namespace std;const ll INF = 9223372036854775807ll;const ll maxn = 3e5+10;struct node{    int u;    ll d;    bool operator < (const node &b)const    {        return d>b.d;    }};struct edge{    int u,v,w,next;}e[maxn*2],newe[maxn];int head[maxn];ll d[maxn];int head1[maxn];bool vis[maxn],in[maxn];int f[maxn];int tot,tot1;int Find(int x){    return f[x]==x?x:f[x]=Find(f[x]);}void add(int u,int v,int w){    e[tot].u=u;    e[tot].v=v;    e[tot].w=w;    e[tot].next=head[u];    head[u]=tot++;}void add1(int u,int v,int w){    newe[tot1].u=u;    newe[tot1].v=v;    newe[tot1].w=w;    tot1++;}void dijkstra(int s,int n){    for(int i=1;i<=n;i++)d[i]=INF;    d[s]=0;    memset(vis,0,sizeof(vis));    priority_queue<node> q;    q.push(node{s,d[s]});    while(!q.empty())    {        node temp = q.top();q.pop();        int u = temp.u;        if(vis[u])continue;        vis[u]=1;        for(int i=head[u];i!=-1;i=e[i].next)        {            int v=e[i].v;            int w=e[i].w;            if(d[v]>d[u]+w*1LL)            {                d[v]=d[u]+w*1LL;                q.push(node{v,d[v]});            }        }    }}bool cmp(edge a,edge b){    return a.w<b.w;}ll Kruscal(int n){    ll ret=0;    memset(in,0,sizeof(in));    for(int i=1;i<=n;i++)f[i]=i;    sort(newe,newe+tot1,cmp);    for(int i=0;i<tot1;i++)    {        int u=newe[i].u,v=newe[i].v,w=newe[i].w;        int xx=Find(u);        int yy=Find(v);        if(in[v]||xx==yy)continue;        in[v]=1;        f[xx]=yy;        ret=ret+w*1LL;    }    return ret;}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        int u,v,w;        memset(head,-1,sizeof(head));        memset(head1,-1,sizeof(head1));        tot=tot1=0;        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&u,&v,&w);            add(u,v,w);            add(v,u,w);        }        int s;        scanf("%d",&s);        dijkstra(s,n);        for(int i=0;i<tot;i+=2)        {            if(d[e[i].v]==d[e[i].u]+1LL*e[i].w)            add1(e[i].u,e[i].v,e[i].w);            if(d[e[i].u]==d[e[i].v]+1LL*e[i].w)            add1(e[i].v,e[i].u,e[i].w);        }        printf("%I64d\n",Kruscal(n));    }}
原创粉丝点击