• hdu 3986 Harry Potter and the Final Battle


    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3986

    题意:给出一个无向图,Harry Potter的目的是从1到n,而Voldemort为了阻止他,使用魔法毁掉了图中的一条边,

    问最坏情况下Harry要走的最短路是多少。

    注意:两点间可以能存在多条路,而且路是双向的,找到最短路后枚举边,求的最短路中最长的那条即为所求,

    #include<iostream>
    #include<queue>
    #include<string>
    using namespace std;
    const int maxn = 1005;
    const int INF = 1<<30;
    struct node
    {
    	int v,w;
    	struct node *next;
    }*head[maxn],edge[50005*2],*p;
    int dis[maxn],per[maxn],n;
    bool vis[maxn];
    queue<int>que;
    void spfa(bool flg)
    {//求起点到终点的最短路
    	for(int i = 1; i <= n; i++)
    		dis[i] = INF;
    	memset(vis,false,sizeof(vis));
    	dis[1] = 0;
    	vis[1] = true;
    	que.push(1);
    	while( !que.empty() )
    	{
    		int now = que.front();
    		que.pop();
    		vis[now] = false;
    		for(p = head[now]; p ; p = p->next)
    		{
    			if(dis[p->v] > dis[now] + p->w)
    			{
    				if(flg)//flg为真表示没有删除边,为假表示求删除某条边后求最短路。
    					per[p->v] = now;
    				dis[p->v] = dis[now] + p->w;
    				if(!vis[p->v])
    				{
    					vis[p->v] = true;
    					que.push(p->v);
    				}
    			}
    		}
    	}
    }
    
    int main()
    {
    	int t,m,i,u,v,w;
    	scanf("%d",&t);
    	while( t-- )
    	{
    		scanf("%d%d",&n,&m);
    		for(i = 1; i <= n; i++)
    			head[i] = NULL;
    		p = edge;
    		while( m-- )
    		{
    			scanf("%d%d%d",&u,&v,&w);
    			p->v = v;p->w = w;
    			p->next = head[u];
    			head[u] = p++;
    			
    			p->v = u;p->w = w;
    			p->next = head[v];
    			head[v] = p++;
    		}
    		memset(per,-1,sizeof(per));
    		spfa(true);
    		
    		int max = -1;
    		if(dis[n] != INF)//存在最短路
    		{
    			
    			node *q1,*q2;
    			for(i = n; per[i] != -1; i = per[i])
    			{
    				int min = INF;
    				q1 = q2 = NULL;
    				//找i和per[i]间距离最短的边
    				for(p = head[per[i]] ; p ; p = p->next)
    				{
    					if(p->v == i && p->w < min)
    					{
    						min = p->w;
    						q1 = p;
    					}
    				}
    
    				for(p = head[i] ; p ; p = p->next)
    				{
    					if(p->v == per[i] && p->w == min)
    					{
    						q2 = p;
    						break;
    					}
    				}
    				//去除边,
    				q1->w = q2->w = INF;
    				spfa(false);
    				//当去除某条边后没有到终点的路径,则结束循环。
    				if(dis[n] >= INF)
    					break;
    				if(dis[n] > max)
    					max = dis[n];
    				//将去除的边还原
    				q1->w = q2->w = min;
    			}
    		}
    		printf("%d\n",max);
    	}
    	return 0;
    }
    


     

  • 相关阅读:
    跨域的几种方式
    jQuery滚动条回到顶部或指定位置
    获取屏幕高度、宽度
    js判断手机系统和微信
    js获取url中的参数
    css3内容溢出属性
    css盒模型
    [转]swagger2 入门教程
    [转]cron表达式的用法
    [转]React入门看这篇就够了
  • 原文地址:https://www.cnblogs.com/LUO257316/p/3220854.html
Copyright © 2020-2023  润新知