标签:
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