您的位置:首页 > 大数据 > 人工智能

hduoj 13375 Flowery Trails

2015-08-10 14:03 288 查看
题目叙述:

给定P个点,T条边。约定起点是第0个点,终点是第P-1的点,求从起点到终点的所有最短路径的边的和乘以二。

难点:

有时候,存在多条路径共享多条边,那么在求和时,就只能加上不共享的边,而不是方案数乘以最短路径的长度。

关键:

标记走过的路径。

代码如下(具体有相应的注释):

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
#define INF 0x3f3f3f3f
#define ll  __int64

const int maxn=10005;

ll sum;
struct Edge
{
Edge(int a,int b):to(a),wi(b){}
int to,wi;
};
vector<Edge> map[maxn];
vector<int> qian[maxn];
vector<int>  path[maxn];
int dis[maxn],P;
bool vis[maxn],vis1[maxn];

void SPFA(int start)
{
queue<int> que;
//    while(!que.empty())  que.pop();

memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));

que.push(start);
vis[start]=1;
dis[start]=0;

while(!que.empty())
{
int top;

top=que.front();
que.pop();
vis[top]=0;

for(int i=0;i<map[top].size();i++)
{
int x=map[top][i].to,wi=map[top][i].wi;

if(dis[x]>dis[top]+wi)//更新最短权值
{
dis[x]=dis[top]+wi;

if(!vis[x])
{
vis[x]=1;
que.push(x);
}

qian[x].clear();
qian[x].push_back(top);//记录到该点的最短路径的前一个点
path[x].clear();
path[x].push_back(i);//记录该点容器的第几条边
}else if(dis[x]==dis[top]+wi)//如果有多条路径就记录多次
{
qian[x].push_back(top);
path[x].push_back(i);
}
}
}
}

void search(int last)
{
if(vis1[last])  {   return;}
vis1[last]=1;//保证不重复计算同一条路径

for(int i=0;i<qian[last].size();i++)
{
int u=qian[last][i];
int v=path[last][i];

sum+=map[u][v].wi;

search(u);
}
}

int main()
{
//    freopen("s","r",stdin);

int T;
while(scanf("%d%d",&P,&T)!=EOF)
{
sum=0;
for(int i=0;i<P;i++)//每次输入点和边,就把之前的容器全部清除
{
map[i].clear();
qian[i].clear();
path[i].clear();
}

for(int i=0;i<T;i++)
{
int p1,p2,l;
scanf("%d%d%d",&p1,&p2,&l);//输入边的两点以及权值

if(p1==p2)  {   continue;}//如果是自环,就没有必要记录,因为最短路径肯定没有自环

Edge x1(p2,l),x2(p1,l);//构建图
map[p1].push_back(x1);
map[p2].push_back(x2);
}

SPFA(0);//通过SPFA算出单源最短路径,并同时通过qian和path记录路径

memset(vis1,0,sizeof(vis1));
search(P-1);//求和

printf("%I64d\n",sum*2);//和的两倍
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: