开始我直接枚举删边 就超时,后来想了下,只要枚举最短路径上的边删除就行了。。。改了下 就AC了
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<set>
using namespace std;
const int inf=999999999;
int n,m,cnt,a,b,l,dis[1010],in[1010],head[1010],mp[1010][1010];
set<int>vt;
struct EDGE
{
int y,l,nxt;
}edge[1000010];
void add(int x,int y,int l)
{
edge[cnt].y=y;
edge[cnt].l=l;
edge[cnt].nxt=head[x];
head[x]=cnt++;
}
void addedge(int x,int y,int l)
{
add(x,y,l);
add(y,x,l);
}
int spfa(int f)
{
fill(dis,dis+n+1,inf);
memset(in,0,sizeof(in));
queue<int>q;
q.push(1);
in[1]=1;
dis[1]=0;
while(!q.empty())
{
int s=q.front();
q.pop();
in[s]=0;
for(int j=head[s];j!=-1;j=edge[j].nxt)
{
int y=edge[j].y,l=edge[j].l;
if((j==f)||((j^1)==f))continue;
if(dis[y]>dis[s]+l)
{
dis[y]=dis[s]+l;
if(!in[y])
{
in[y]=1;
q.push(y);
}
}
}
}
return dis[n];
}
void dfs(int x)
{
if(x==1)return;
for(int j=head[x];j!=-1;j=edge[j].nxt)
{
int y=edge[j].y,l=edge[j].l;
if(dis[y]+l==dis[x])
{
vt.insert(j);
dfs(y);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
cnt=0;
memset(head,-1,sizeof(head));
memset(mp,0,sizeof(mp));
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&l);
if(a==b)continue;
if(mp[a][b]==0)
{
mp[a][b]=mp[b][a]=l;
}
else
mp[a][b]=min(mp[a][b],l);
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(mp[i][j])
{
addedge(i,j,mp[i][j]);
}
}
int ans=0;
spfa(-1);
vt.clear();
dfs(n);
for(set<int>::iterator it=vt.begin();it!=vt.end();++it)
{
ans=max(spfa(*it),ans);
}
printf("%d\n",ans);
}
return 0;
}