您的位置:首页 > 其它

HDU 3986 Harry Potter and the Final Battle Dijkstra + 堆优化

2013-08-24 16:20 465 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3986

题意:

  起点为1,终点为N,伏地魔会将任意一条路径删除,要求算出删除任意一条边后的最短路径中最大的一个,

伏地魔的角度来说就是,想删一条路harry走到终点的距离尽可能大。

坑爹:

  有重边,有反向边。删边的时候要记得连反边一起删除。

解法:

  用了个dijkstra + 堆优化的模板,因为伏地魔要删除harry的最短路径上的边才起到干扰的效果,所以枚举删除

最短路径上的每一条边,每枚举一次计算出一次最短路,只要有计算不出的就输出-1,不然就输出最大的最短路。

#include<iostream>
#include<vector>
#include<set>
using namespace std;

const int maxn = 100000 + 10;
const int INF = 0x3fffffff;

struct Edge {
int from;
int to;
int values;
int next;
}edge[maxn];

int t;
int n;
int m;
int count_Edge;
int dis[maxn];
bool used[maxn];
int pre[maxn];
int path[maxn];
bool used_Edge[maxn];
int path_Edge[maxn];

struct cmp {
bool operator () (const int &a,const int &b) const
{
if(dis[a] == dis[b])
{
return a < b;
}
return dis[a] < dis[b];
}
};

void initDis()
{
memset(used,0,sizeof(used));
int i;
for(i=0; i<maxn; i++)
{
dis[i] = INF;
}
}

void init()
{
count_Edge = 0;
memset(used_Edge,0,sizeof(used_Edge));
memset(path,-1,sizeof(path));
memset(path_Edge,-1,sizeof(path_Edge));
memset(pre,-1,sizeof(pre));
memset(edge,0,sizeof(edge));
initDis();
}

void addEdge(int from, int to, int values)
{
edge[count_Edge].from = from;
edge[count_Edge].to = to;
edge[count_Edge].values = values;
edge[count_Edge].next = pre[from];
pre[from] = count_Edge++;

edge[count_Edge].from = to;
edge[count_Edge].to = from;
edge[count_Edge].values = values;
edge[count_Edge].next = pre[to];
pre[to] = count_Edge++;
}

int dijkstra(int begin,int end,int flag)
{
set<int,cmp> S;
S.clear();
dis[begin] = 0;
path[begin] = begin;
S.insert(begin);
while(!S.empty())
{
int st = *S.begin();
if(st == end)
{
return dis[end];
}
S.erase(st);
used[st] = true;
int i;
for(i = pre[st]; i != -1; i = edge[i].next)
{
Edge e = edge[i];
if(!used[e.to] && dis[e.to] > dis[st] + e.values && !used_Edge[i])
{
S.erase(e.to);
path[e.to] = st;
if(!flag)
{
path_Edge[e.to] = i;
}
dis[e.to] = dis[st] + e.values;
S.insert(e.to);
}
}
}
return -1;
}

int main()
{
cin>>t;
while(t--)
{
init();
cin>>n>>m;
int i;
for(i=0; i<m; i++)
{
int from;
int to;
int values;
cin>>from>>to>>values;
addEdge(from, to, values);
}
int ans = dijkstra(1,n,0);
if(ans == -1 || ans == INF)
{
cout<<-1<<endl;
continue;
}
int cut[maxn];
int k = 0;
int x = n;
int max =  -1;
while(path_Edge[x] != -1)
{
initDis();
used_Edge[path_Edge[x]] = true;
used_Edge[path_Edge[x]^1] = true;
ans = dijkstra(1,n,1);
if(ans == -1 || dis
== INF)
{
max = -1;
break;
}
if(max < ans)
{
max = ans;
}
used_Edge[path_Edge[x]] = false;
used_Edge[path_Edge[x]^1] = false;
x = edge[path_Edge[x]].from;
}
cout<<max<<endl;
}
return 0;
}

/*
1
2 2
1 2 1
1 2 1

10
3 4
1 2 10
2 1 11
3 2 10
3 2 11

10
2 3
1 2 1
1 2 2
1 2 3
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: