为了图。计算最短随机分ans1。和删除边缘。免费才能够获得最大和短路之间的最大分ans2,如果这两个不沟通。看作是两个点之间的最短距离l。
第一个想法是枚举每个边缘,然后运行n最短时间。但是,这种复杂性是1000*1000*100*log(100),太大了..事实上在固定起点,求出单元最短路的时候。同一时候能够求出单源最短路树,仅仅有删除的边在树上的时候。源点到任一点的最短路才会有变化,所以在每次跑单源最短路的时候,仅仅须要枚举树上的n-1条边就能够了。累加一下删除每一条边时,在当前源点的情况下。最短距离之和的添加量,最后枚举找一条添加量最大的边就能够了。
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <cstring> #include <vector> using namespace std; typedef long long ll; const ll inf=(1LL<<61); ll cost[2020]; int n,m; ll l; struct HeapNode { ll d; int u; bool operator< (const HeapNode& rhs) const { return d>rhs.d; } HeapNode(){} HeapNode(ll x,int y) { d=x; u=y; } }; struct Edge { int u,v; ll w; bool ok; Edge(){} Edge(int x,int y,ll z) { u=x; v=y; w=z; ok=true; } }; const int maxn=105; struct Dij { int n,m; vector<Edge> edges; vector<int> G[maxn]; bool done[maxn]; ll d[maxn]; int p[maxn]; void init(int n) { this->n=n; for (int i=0; i<=n; i++) { G[i].clear(); } edges.clear(); } void addedge(int x,int y,ll z) { edges.push_back((Edge(x,y,z))); m=edges.size(); G[x].push_back(m-1); } void dijkstra(int s) { priority_queue<HeapNode> q; for (int i=0; i<=n; i++) d[i]=inf; d[s]=0; memset(done,0,sizeof done); memset(p,-1,sizeof p); q.push(HeapNode(0,s)); while(!q.empty()) { HeapNode x=q.top(); q.pop(); int u=x.u; if (done[u]) continue; done[u]=true; for (int i=0; i<G[u].size(); i++) { Edge &e=edges[G[u][i]]; if (!e.ok) continue; if (d[e.v]>d[u]+e.w) { d[e.v]=d[u]+e.w; p[e.v]=G[u][i]; q.push(HeapNode(d[e.v],e.v)); } } } } int tp[maxn]; ll slove(int s) { ll res=0; ll add=0; ll tmp=0; ll maxx=0; for (int i=1; i<=n; i++) { if (d[i]<inf)res+=d[i]; else res+=l; } memcpy(tp,p,sizeof p); for (int i=1;i<=n; i++) { if (tp[i]!=-1) { edges[tp[i]].ok=false; edges[tp[i]^1].ok=false; dijkstra(s); tmp=0; for (int j=1; j<=n; j++) { if (d[j]<inf) tmp+=d[j]; else tmp+=l; } cost[tp[i]]+=(tmp-res); cost[tp[i]^1]+=(tmp-res); edges[tp[i]].ok=true; edges[tp[i]^1].ok=true; } } return res; } }work; int main() { // freopen("in.txt","r",stdin); while (~scanf("%d%d%lld",&n,&m,&l)) { int x,y; ll z; work.init(n); for (int i=1; i<=m; i++) { scanf("%d%d%lld",&x,&y,&z); work.addedge(x,y,z); work.addedge(y,x,z); } memset(cost,0,sizeof cost); ll ans=0; for (int i=1; i<=n; i++) { work.dijkstra(i); ans+=work.slove(i); } int id=0; ll maxx=0; ll ans2=0; for (int i=0; i<work.edges.size(); i++) { if (cost[i]>maxx) { id=i; maxx=cost[i]; } } work.edges[id].ok=false; work.edges[id^1].ok=false; for (int i=1; i<=n; i++) { work.dijkstra(i); for (int j=1; j<=n; j++) if (work.d[j]<inf) ans2+=work.d[j]; else ans2+=l; } cout<<ans<<" "<<ans2<<endl; } return 0; }
版权声明:本文博主原创文章。博客,未经同意不得转载。