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

3.给一张图，有三种操作：
1.询问两点间的最短路
2.询问整张图的最小生成树
3.加边

#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];

{
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));
for(int i = 1; i <= m; i ++)
{
build(e[i].f,e[i].t,e[i].v);
build(e[i].t,e[i].f,e[i].v);
}
for(int i = 1; i <= qq; i ++)
{
if(p == 1)
{
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 ++;
build(e[m].f,e[m].t,e[m].v);
build(e[m].t,e[m].f,e[m].v);
}
}
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120