标签:
Description
Input
Output
Sample Input
2 2 2 1 2 13 2 1 33 4 6 1 2 10 2 1 60 1 3 20 3 4 10 2 4 5 4 1 50
Sample Output
46 210
题解:求1到其他点和其他点的和的最小值,正向建图和逆向建图后两次都求1到其他点的最小值之和就行。但是数据较大,用vector超时,需要自己建立邻接表。
djistra(堆优化 + 动态建图) 7000ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int INF = 1000000008;
struct Node
{
int to;
int cost;
Node(int a,int b)
{
to = a;
cost = b;
}
bool operator< (Node t) const
{
return cost > t.cost;
}
};
struct Node1
{
int from;
int to;
Node1* next;
int cost;
Node1(){
}
Node1(int a,int b,int c,Node1* t = NULL)
{
from = a;
to = b;
cost = c;
next = t;
}
};
Node1 vec[2][1000006];
bool visited[1000006];
int d[1000006];
long long ans;
void prim(int n,int flag)
{
memset(visited,false,sizeof(visited));
for(int i = 1;i <= n;i++)
{
d[i] = INF;
}
d[1] = 0;
priority_queue<Node> q;
q.push(Node(1,0));
while(!q.empty())
{
Node p = q.top();
q.pop();
if(visited[p.to])
{
continue;
}
visited[p.to] = true;
ans += p.cost;
for(Node1* pp = vec[flag][p.to].next;pp != NULL;pp = pp->next)
{
int t = pp->to;
if(!visited[t] && d[t] > d[p.to] + pp->cost)
{
d[t] = d[p.to] + pp->cost;
q.push(Node(t,d[t]));
}
}
}
}
int main()
{
int ncase;
cin>>ncase;
while(ncase--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
{
vec[0][i].next = NULL;
vec[1][i].next = NULL;
}
for(int i = 0;i < m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
Node1* p = new Node1(u,v,c);
p->next = vec[0][u].next;
vec[0][u].next = p;
p = new Node1(v,u,c);
p->next = vec[1][v].next;
vec[1][v].next = p;
}
ans = 0;
prim(n,0);
prim(n,1);
printf("%lld\n",ans);
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int INF = 1000000008;
struct Node
{
int from;
int to;
int cost;
Node(){
}
Node(int a,int b,int c)
{
from = a;
to = b;
cost = c;
}
bool operator< (Node t) const
{
return cost > t.cost;
}
};
Node vec[2][1000006];
bool visited[1000006];
int d[1000006];
int first[2][1000006];
int next[2][1000006];
long long ans;
void prim(int n,int flag)
{
memset(visited,false,sizeof(visited));
for(int i = 1;i <= n;i++)
{
d[i] = INF;
}
d[1] = 0;
priority_queue<Node> q;
q.push(Node(1,1,0));
while(!q.empty())
{
Node p = q.top();
q.pop();
if(visited[p.to])
{
continue;
}
visited[p.to] = true;
ans += p.cost;
for(int i = first[flag][p.to];i != -1;i = next[flag][i])
{
int t = vec[flag][i].to;
if(!visited[t] && d[t] > d[p.to] + vec[flag][i].cost)
{
d[t] = d[p.to] + vec[flag][i].cost;
q.push(Node(p.to,t,d[t]));
}
}
}
}
int main()
{
int ncase;
cin>>ncase;
while(ncase--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
{
first[0][i] = -1;
first[1][i] = -1;
}
for(int i = 0;i < m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
vec[0][i].from = u;
vec[0][i].to = v;
vec[0][i].cost = c;
next[0][i] = first[0][u];
first[0][u] = i;
vec[1][i].from = v;
vec[1][i].to = u;
vec[1][i].cost = c;
next[1][i] = first[1][v];
first[1][v] = i;
}
ans = 0;
prim(n,0);
prim(n,1);
printf("%lld\n",ans);
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int INF = 1000000008;
struct Node
{
int to;
int cost;
Node(int a,int b)
{
to = a;
cost = b;
}
bool operator< (Node t) const
{
return cost < t.cost;
}
};
struct Node1
{
int from;
int to;
Node1* next;
int cost;
Node1(){
}
Node1(int a,int b,int c,Node1* t = NULL)
{
from = a;
to = b;
cost = c;
next = t;
}
};
Node1 vec[2][1000006];
bool visited[1000006];
int d[1000006];
long long ans;
void spfa(int n,int flag)
{
for(int i = 1;i <= n;i++)
{
d[i] = INF;
}
d[1] = 0;
queue<int> q;
q.push(1);
visited[1] = true;
while(!q.empty())
{
int x = q.front();
q.pop();
visited[x] = false;
for(Node1* p = vec[flag][x].next;p != NULL;p = p->next)
{
int t = p->to;
//cout<<p->cost<<" ";
if(d[t] > d[x] + p->cost)
{
d[t] = d[x] + p->cost;
if(!visited[t])
{
visited[t] = true;
q.push(t);
}
}
}
}
}
int main()
{
int ncase;
cin>>ncase;
while(ncase--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
{
vec[0][i].next = NULL;
vec[1][i].next = NULL;
}
for(int i = 0;i < m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
Node1* p = new Node1(u,v,c);
p->next = vec[0][u].next;
vec[0][u].next = p;
p = new Node1(v,u,c);
p->next = vec[1][v].next;
vec[1][v].next = p;
}
ans = 0;
spfa(n,0);
for(int i = 2;i <= n;i++)
{
ans += d[i];
}
spfa(n,1);
for(int i = 2;i <= n;i++)
{
ans += d[i];
}
printf("%lld\n",ans);
}
return 0;
}#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int INF = 1000000008;
struct Node
{
int to;
int cost;
Node(){
}
Node(int a,int b)
{
to = a;
cost = b;
}
bool operator< (Node t) const
{
return cost < t.cost;
}
};
Node vec[2][1000006];
bool visited[1000006];
int d[1000006];
int first[2][1000006];
int next[2][1000006];
long long ans;
void spfa(int n,int flag)
{
for(int i = 1;i <= n;i++)
{
d[i] = INF;
}
d[1] = 0;
queue<int> q;
q.push(1);
visited[1] = true;
while(!q.empty())
{
int x = q.front();
q.pop();
visited[x] = false;
for(int i = first[flag][x];i != -1;i = next[flag][i])
{
int t = vec[flag][i].to;
if(d[t] > d[x] + vec[flag][i].cost)
{
d[t] = d[x] + vec[flag][i].cost;
if(!visited[t])
{
visited[t] = true;
q.push(t);
}
}
}
}
}
int main()
{
int ncase;
cin>>ncase;
while(ncase--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
{
first[0][i] = -1; //编号为i的邻接点(该条边的下标)初始化为-1,表示该点没邻接点
first[1][i] = -1;
}
for(int i = 0;i < m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
vec[0][i].to = v;
vec[0][i].cost = c;
next[0][i] = first[0][u]; //u的新的邻接点取代了u以前的邻接点,新的邻接点保存以前邻接点的位置
first[0][u] = i; //u的第一个邻接点被新的取代,输出u的邻接点时和输入刚好相反
vec[1][i].to = u;
vec[1][i].cost = c;
next[1][i] = first[1][v]; //u的新的邻接点取代了u以前的邻接点,新的邻接点保存以前邻接点的位置
first[1][v] = i; //u的第一个邻接点被新的取代,输出u的邻接点时和输入刚好相反
}
ans = 0;
spfa(n,0);
for(int i = 2;i <= n;i++)
{
ans += d[i];
}
spfa(n,1);
for(int i = 2;i <= n;i++)
{
ans += d[i];
}
printf("%lld\n",ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/wang2534499/article/details/47750821