poj 1511 Invitation Cards(2遍spfa)
2015-07-30 16:40
288 查看
题目地址
题目大意:n个站,告诉站之间的权值,求从1到所有点并返回1的最小权值和
解题思路:对1进行单源spfa,返回的时候因为spfa只能单源,所以将原图转置,再对1进行一次spfa,图的转置需要特殊处理,我采用的是邻接表存储图,相当于建了2个图
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
const int maxn = 1000000+10;
const int INF = 0xfffffff;
int dis[maxn],head[maxn],vis[maxn],cnt,n,m;
int u[maxn],v[maxn],w[maxn];
struct Edge
{
int to,next,w;
}e[maxn];
void addEdge(int u,int v,int w)
{
e[cnt].to = v;
e[cnt].w = w;
e[cnt].next = head;
head[u] = cnt++;
}
void spfa()
{
queue<int> q;
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i++)
dis[i] = INF;
q.push(1);
vis[1] = 1;
dis[1] = 0;
while(!q.empty())
{
int v = q.front();
q.pop();
vis[v] = 0;
for(int i = head[v]; i != -1; i = e[i].next)
{
if(dis[e[i].to] > dis[v]+e[i].w)
{
dis[e[i].to] = dis[v]+e[i].w;
if(!vis[e[i].to])
{
vis[e[i].to] = 1;
q.push(e[i].to);
}
}
}
}
}
void graph1()
{
cnt = 1;
memset(head,-1,sizeof(head));
for(int i = 1; i <= m; i++)
addEdge(u[i],v[i],w[i]);
}
void graph2()
{
cnt = 1;
memset(head,-1,sizeof(head));
for(int i = 1; i <= m; i++)
addEdge(v[i],u[i],w[i]);
}
int main()
{
int t,sum;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
}
sum = 0;
graph1();
spfa();
for(int i = 2; i <= n; i++)
sum += dis[i];
graph2();
spfa();
for(int i = 2; i <= n; i++)
sum += dis[i];
printf("%d\n",sum);
}
return 0;
}
[u]
题目大意:n个站,告诉站之间的权值,求从1到所有点并返回1的最小权值和
解题思路:对1进行单源spfa,返回的时候因为spfa只能单源,所以将原图转置,再对1进行一次spfa,图的转置需要特殊处理,我采用的是邻接表存储图,相当于建了2个图
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
const int maxn = 1000000+10;
const int INF = 0xfffffff;
int dis[maxn],head[maxn],vis[maxn],cnt,n,m;
int u[maxn],v[maxn],w[maxn];
struct Edge
{
int to,next,w;
}e[maxn];
void addEdge(int u,int v,int w)
{
e[cnt].to = v;
e[cnt].w = w;
e[cnt].next = head;
head[u] = cnt++;
}
void spfa()
{
queue<int> q;
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i++)
dis[i] = INF;
q.push(1);
vis[1] = 1;
dis[1] = 0;
while(!q.empty())
{
int v = q.front();
q.pop();
vis[v] = 0;
for(int i = head[v]; i != -1; i = e[i].next)
{
if(dis[e[i].to] > dis[v]+e[i].w)
{
dis[e[i].to] = dis[v]+e[i].w;
if(!vis[e[i].to])
{
vis[e[i].to] = 1;
q.push(e[i].to);
}
}
}
}
}
void graph1()
{
cnt = 1;
memset(head,-1,sizeof(head));
for(int i = 1; i <= m; i++)
addEdge(u[i],v[i],w[i]);
}
void graph2()
{
cnt = 1;
memset(head,-1,sizeof(head));
for(int i = 1; i <= m; i++)
addEdge(v[i],u[i],w[i]);
}
int main()
{
int t,sum;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
}
sum = 0;
graph1();
spfa();
for(int i = 2; i <= n; i++)
sum += dis[i];
graph2();
spfa();
for(int i = 2; i <= n; i++)
sum += dis[i];
printf("%d\n",sum);
}
return 0;
}
[u]
相关文章推荐
- XP本地用户配置文件转为域用户配置文件
- 树和二叉树的学习——树的编号,nyoj,小猴子下落 就可以仿写
- Xcode 7:无需99刀也能在真机上测试App
- HTML5定稿,为什么是原生App的颠覆
- c++中size_type和size_t的关系
- GTK帮助文档的使用
- netty concepts
- 技术教程网址
- CentOS安装配置JDK环境
- 【Android应用开发技术:数据存储】数据库
- 牛顿迭代法求解多元高阶方程组
- FastCgi与PHP-fpm之间是个什么样的关系
- hdu 4028 2011上海赛区网络赛H dp+map离散
- Swift开发教程--字符串的操作
- WinXP、Win7脚本自动加域及用户资料迁移
- C#读取XML流数据
- python如何实现excel数据添加到mongodb
- 判断手机是否有root权限
- CIO客观评价SAP和用友的差异
- 【Android应用开发技术:文件读写】Android文件系统