您的位置:首页 > 其它

la4080 Warfare And Logistics 罗列+最短

2015-09-22 09:28 381 查看
为了图。计算最短随机分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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: