题意:
给了一个无向图...问两两间最短距离之和为多少..当两点不可达时..那么令其距离为L...现在还能删去一条边..问所能得到的两两之和最大为多少...
题解:
先做N次dijkstra..记录每个点位源点的djikstra中有哪些边...并且得到原始状态下两两间距离之和...
然后就是枚举删哪条边...枚举一条边...扫N个点..看这条边是否在某些记录中..如果有..则对于这些点重新做djikstra...更新答案即可..
恶心的是数据范围...开成105,2005..狂WA不止...开成155,2055才给过...还有注意的是Uva的64位整型用%lld读入读出..
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<set> #include <stack> #include<queue> #include<algorithm> #include<cmath> #define oo 1000000007 #define ll long long #define pi acos(-1.0) #define MAXN 155 #define MAXM 2505 using namespace std; struct node { int u,v,id,next; ll c; }edge[MAXM]; struct NODE { int u,id; ll c; bool operator <(NODE a) const { return a.c<c; } }; int Ne,_next[MAXN]; ll dis[MAXN][MAXN],t_dis[MAXN][MAXN],L; bool b[MAXN][MAXM],t_b[MAXN][MAXM],used[MAXN]; void addedge(int u,int v,int c,int id) { edge[++Ne].next=_next[u],_next[u]=Ne,edge[Ne].id=id; edge[Ne].u=u,edge[Ne].v=v,edge[Ne].c=c; } priority_queue<NODE> Q; void dijkstra(int s,int n,int fbt) { NODE h,k; int u,v,i; while (!Q.empty()) Q.pop(); memset(used,false,sizeof(used)); memset(dis[s],-1,sizeof(dis[s])); memset(b[s],false,sizeof(b[s])); dis[s][s]=0,h.u=s,h.c=h.id=0,Q.push(h); while (!Q.empty()) { while (Q.size() && used[Q.top().u]) Q.pop(); if (!Q.size()) break; h=Q.top(),Q.pop(); used[h.u]=true,b[s][h.id]=true; for (i=_next[h.u];i;i=edge[i].next) if (edge[i].id!=fbt) { v=edge[i].v; if (dis[s][v]==-1 || dis[s][v]>h.c+edge[i].c) { dis[s][v]=h.c+edge[i].c; k.u=v,k.c=dis[s][v],k.id=edge[i].id,Q.push(k); } } } dis[s][0]=0; for (i=1;i<=n;i++) if (dis[s][i]==-1) dis[s][0]+=L; else dis[s][0]+=dis[s][i]; } int main() { int n,m,i,j,t,u,v,s; ll c1,c2,t_c; while (~scanf("%d%d%lld",&n,&m,&L)) { Ne=0,memset(_next,0,sizeof(_next)); for (i=1;i<=m;i++) scanf("%d%d%d",&u,&v,&s),addedge(u,v,s,i),addedge(v,u,s,i); for (i=1;i<=n;i++) dijkstra(i,n,0); c1=0; for (i=1;i<=n;i++) c1+=dis[i][0]; memcpy(t_dis,dis,sizeof(dis)); memcpy(t_b,b,sizeof(dis)); c2=0; for (t=1;t<=m;t++) { memcpy(dis,t_dis,sizeof(dis)); memcpy(b,t_b,sizeof(dis)); t_c=c1; for (u=1;u<=n;u++) if (b[u][t]) { t_c-=dis[u][0]; // dis[u][0]记录之和 dijkstra(u,n,t); t_c+=dis[u][0]; } c2=max(c2,t_c); } printf("%lld %lld\n",c1,c2); } return 0; }