大数据完全图

来源:互联网 发布:局域网网站搭建 ubuntu 编辑:程序博客网 时间:2024/04/28 01:13
/**
SCU - 4444 别样最短路径-大数据完全图
题目大意:给定一个完全图,其中有两种边,长度为a(不超过5e5)或长度为b(剩下的),求有1~n的最短路径(数据范围1e5)
解题思路:如果1和n之间连边为a那么答案一定为a和一条最短的全由b组成的路径的较小者,如果1和n之间连边为b,那么答案一定
           为b和一条最短的全由a组成的路径的较小者。对于第1种情况直接跑spfa就可以了,第二种情况由于边数较多,不能直接spfa
           从1开始搜索与其相连的边权为b的边,用set维护一下,由于每个点只入队1次,复杂度还是允许的。这种处理方法还是第一
           次做,感觉很巧妙

*/

st 保存的是未访问过的顶点的集合, ts 从名字就可以看出是用来临时装一下未访问过的顶点的,从而让st的可以放心的去更新- -。

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <set>#include <queue>using namespace std;typedef long long LL;const int INF=1e9+7;const int maxn=100100;int n,m,vis[maxn];LL a,b,dis[maxn];set<int>st,ts;set<int>::iterator it;int head[maxn],ip;void init(){    memset(head,-1,sizeof(head));    ip=0;}struct note{    int v,next;}edge[maxn*10];void addedge(int u,int v){    edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++;}void spfa(){    queue<int>q;    for(int i=0;i<=n;i++)dis[i]=INF;    memset(vis,0,sizeof(vis));    dis[1]=0;    q.push(1);    while(!q.empty())    {        int u=q.front();        q.pop();        vis[u]=0;        for(int i=head[u];i!=-1;i=edge[i].next)        {            int v=edge[i].v;            if(dis[v]>dis[u]+1)            {                dis[v]=dis[u]+1;                if(!vis[v])                {                    vis[v]=1;                    q.push(v);                }            }        }    }    printf("%lld\n",min(dis[n]*a,b));}void bfs(){    dis[n]=INF;    st.clear(),ts.clear();    for(int i=2;i<=n;i++)st.insert(i);    queue<int>q;    q.push(1);    dis[1]=0;    while(!q.empty())    {        int u=q.front();        q.pop();        for(int i=head[u];i!=-1;i=edge[i].next)        {            int v=edge[i].v;            if(st.count(v)==0)continue;            st.erase(v),ts.insert(v);        }        for(it=st.begin();it!=st.end();it++)        {            q.push(*it);            dis[*it]=dis[u]+1;        }        st.swap(ts);        ts.clear();    }    printf("%lld\n",min(dis[n]*b,a));}int main(){    while(~scanf("%d%d%lld%lld",&n,&m,&a,&b))    {        init();        int flag=0;        for(int i=0;i<m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            if(u>v)swap(u,v);            addedge(u,v);            addedge(v,u);            if(u==1&&v==n)flag=1;        }        if(flag)bfs();        else spfa();    }    return 0;}

0 0
原创粉丝点击