【模板】最短路&&最小生成树

来源:互联网 发布:东京食尸鬼面具淘宝 编辑:程序博客网 时间:2024/05/23 01:59

3.给一张图,有三种操作:
1.询问两点间的最短路
2.询问整张图的最小生成树
3.加边
都是双向边,数据范围1 <= n <= 10000,1 <= m <= 100000 1 <= q <= 100;

论最短路的正(防)确(爆)写法
论最小生成树的正确玩法
论加边的正确处理

最短路给出Dijkstra和spfa
最小生成树使用kruskal

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int MAXN = 2000005;const int INF = 2147483641;int first[MAXN],next[MAXN],dis[MAXN];int n,m,qq,se,ee,p,tot = 0;int fa[MAXN],deep[MAXN];bool use[MAXN];inline int read(){    char ch = getchar();    int f = 1, x = 0;    while(!(ch >= '0' && ch <= '9')){if(ch == '-')f=-1;ch = getchar();}    while(ch >= '0' && ch <= '9') {x = x* 10 + (ch- '0');ch = getchar();}    return x * f;} void init(){    memset(deep,0,sizeof(deep));    for(int i = 1; i <= n; i ++)        fa[i] = i;    return;}struct edge{    int f,t,v;}l[MAXN],e[MAXN];void build(int f,int t,int v){    l[++ tot] = (edge){f,t,v};    next[tot] = first[f];    first[f] = tot;    return;}bool cmp(edge a,edge b){    return a.v < b.v;}deque < int >q;void spfa(int s){    memset(dis,0x3f,sizeof(dis));    memset(use,0,sizeof(use));    dis[s] = 0;    use[s] = true;    while(!q.empty())   q.pop_front();    q.push_back(s);    q.push_back(0);    while(!q.empty())    {        int u = q.front();        use[u] = false;        q.pop_front();        for(int i = first[u]; i != -1; i = next[i])        {            int w = l[i].t;            if(dis[w] > dis[u] + l[i].v)            {                dis[w] = dis[u] + l[i].v;                if(use[w] == false)                {                    use[w] = true;                    if(q.empty())   q.push_back(w);                    if(dis[w] < dis[q.front()])                        q.push_front(w);                    else                        q.push_back(w);                }            }        }    }    return;}/*struct re{    int u,v;    bool operator < (const re &b)const    {        return v > b.v;    }};priority_queue < re > q;int dij(int s,int e){    memset(use,0,sizeof(use));    while(!q.empty())   q.pop();    q.push((re){s,0});    while(!q.empty())    {        re us = q.top();        q.pop();        int u = us.u;        if(u == e)  return us.v;        if(use[u])  continue;        use[u] = true;        for(int i = first[u]; i != -1; i = next[i])        {            int w = l[i].t;            int rs = us.v + l[i].v;            q.push((re){w,rs});        }    }    return -1;}*/int find(int x){    return x == fa[x] ? x : fa[x] = find(fa[x]);}void merge(int x,int y){    x = find(x),y = find(y);    if(deep[x] > deep[y])        swap(x,y);    fa[x] = y;    if(deep[x] == deep[y])        deep[y] ++;    return;}bool same(int x,int y){    return find(x) == find(y);}int kru(){    sort(e + 1,e + 1 + m,cmp);    init();    int ans = 0;    for(int i = 1; i <= m; i ++)        if(!same(e[i].f,e[i].t))            ans += e[i].v,merge(e[i].f,e[i].t);    return ans;}int main(){    memset(first,0xff,sizeof(first));    n = read(),m = read();    for(int i = 1; i <= m; i ++)    {        e[i].f = read(),e[i].t = read(),e[i].v = read();        build(e[i].f,e[i].t,e[i].v);        build(e[i].t,e[i].f,e[i].v);    }    qq = read();    for(int i = 1; i <= qq; i ++)    {        p = read();        if(p == 1)        {            se = read(),ee = read();            spfa(se);            printf("%d\n",dis[ee]);        //  printf("%d\n",dij(se,ee));        }        else if(p == 2)            printf("%d\n",kru());        else if(p == 3)        {            m ++;            e[m].f = read(),e[m].t = read(),e[m].v = read();            build(e[m].f,e[m].t,e[m].v);            build(e[m].t,e[m].f,e[m].v);        }    }    return 0;}
1 0
原创粉丝点击