HDU 3986 Harry Potter and the Final Battle

/*
题意:在一张图上删去一条边,使得从1到n的最短路最长
刚开始枚举要删去的边x,求最短路,复杂度是m*n*log(n);果断tle了
后来想想只要在不删边的情况下求得最短路,记录最短路经过的边,然后枚举这些边中的一条为删去的边求最短路,使得这个值最多即可
很显然,删去的边不是原先最短路上的边最短路没有变,不会有影响,所以不必枚举
*/
#include <cstdio>
#include <iostream>
#include <memory.h>
#include<queue>
#include<set>
#include<ctime>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdio>
using namespace std;
const int MAXV=1009;
const int MAXE=100009;
const int INF=1<<30;
int n;
struct Edge
{
    int v,w,next;
}edge[MAXE];
int first[MAXV];
int mark[MAXE];
int d[MAXV];
int fa[MAXV];//记录x节点的前驱节点
int L[MAXE];//记录从x的前驱到x走的是哪一条边,处理重边的情况
int vis[MAXV];
int e,m;
void add(int u,int v,int w)
{
    edge[e].v=v;
    edge[e].w=w;
    edge[e].next=first[u];
    first[u]=e;
    
    edge[e+m].v=u;
    edge[e+m].w=w;
    edge[e+m].next=first[v];
    first[v]=e+m;
    
    e++;
}
typedef pair<int,int> pii;
int dij(int k)//k为1为第一次求最短路,为0表示删边后求最短路
{
    priority_queue<pii,vector<pii>,greater<pii> > q;
    for(int i=1;i<=n;i++)
    {
        d[i]=INF;
        vis[i]=0;
    }
    d[1]=0;
    q.push(make_pair(0,1));
    while(!q.empty())
    {
        pii u=q.top();q.pop();
        int x=u.second;
        if(vis[x])continue;
        //if(d[n]<INF)break;
        vis[x]=1;
        for(int e=first[x];e!=-1;e=edge[e].next)
        {
            int v=edge[e].v;
            if(k==0&&mark[v]&&(L[v]==e||L[v]==e+m))continue;
            if(d[v]>d[x]+edge[e].w)
            {
                d[v]=d[x]+edge[e].w;
                if(k==1)
                {
                fa[v]=x;
                L[v]=e;
                }
                q.push(make_pair(d[v],v));
            }
        }
    }
    return d[n];
}
int main()
{
    int ca,u,v,w;
    scanf("%d",&ca);
    while(ca--)
    {
        e=1;
        memset(first,-1,sizeof(first));
        memset(mark,0,sizeof(mark));
        memset(L,0,sizeof(L));
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        dij(1);
        int ans=-1;
        for (int i=n;i!=1;i=fa[i])
        {
            mark[i]=1;
            int tmp=dij(0);
            if(tmp==INF)
            {
            ans=-1;
            break;
            }
            if(tmp>ans)
            ans=tmp;
            mark[i]=0;
        }
        printf("%d\n",ans);
    }
}        

你可能感兴趣的:(pair)