UVA 1416 Warare And Logistics(dijkstra)

思路是先暴力算出每个点的出发的最短路,然后记录下最短路树的边,枚举边,如果是最短路树上的边,那么可以删除,此时再做了一次djikstra。

自己想的时候非常贴合这个思路了,感觉只能暴力了,但是感觉这样做时间复杂度太高,最后算了下时间复杂度O(n^2mlogn),大概是刚好1e8,刚好卡着时间范围= = 。

以后想到思路还是仔细算一下复杂度,然后再决定写不写,好多次感觉时间爆了不敢写。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn=100+5;
const int inf=100000000;
struct HeapNode{
    int d,u;
    bool operator < (const HeapNode &rhs) const {
        return d>rhs.d;
    }
};
struct edge{
    int from,to,dist;
};
struct Dijkstra{
    int n,m;
    vector<edge> edges;
    vector<int> G[maxn];
    bool done[maxn];
    int 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 from,int to,int dist){
        edges.push_back((edge){from,to,dist});
        m=(int)edges.size();
        G[from].push_back(m-1);
    }
    
    void dijkstra(int s){
        priority_queue<HeapNode> pq;
        for(int i=0;i<n;i++) d[i]=inf;
        d[s]=0;
        memset(done,0,sizeof(done));
        pq.push((HeapNode){0,s});
        while(!pq.empty()){
            HeapNode x=pq.top();pq.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(d[e.to]>d[u]+e.dist){
                    d[e.to]=d[u]+e.dist;
                    p[e.to]=G[u][i];
                    pq.push((HeapNode){d[e.to],e.to});
                }
            }
        }
    }
};

Dijkstra dij;
int used[maxn][maxn][maxn];
int sum_sigal[maxn];
int idx[maxn][maxn];
vector<int> gr[maxn][maxn];
int ans1,ans2;
int n,m,L;
void solve(){
    memset(used,0,sizeof(used));
    for(int src=0;src<n;src++){
        dij.dijkstra(src);
        sum_sigal[src]=0;
        for(int i=0;i<n;i++){
            if(src!=i){
                int fa=dij.edges[dij.p[i]].from;
                used[src][fa][i]=used[src][i][fa]=1;
            }
            sum_sigal[src]+=dij.d[i]==inf?L:dij.d[i];
        }
        ans1+=sum_sigal[src];
    }
}
int solve_new(int i,int j)
{
    int tmp=0;
    for(int src=0;src<n;src++){
        if(!used[src][i][j]) tmp+=sum_sigal[src];
        else{
            dij.dijkstra(src);
            for(int k=0;k<n;k++) tmp+=dij.d[k]==inf?L:dij.d[k];
        }
    }
    return tmp;
}
int main()
{
    while(~scanf("%d%d%d",&n,&m,&L))
    {
        dij.init(n);
        for(int i=0;i<n;i++) for(int j=0;j<n;j++) gr[i][j].clear();
        int u,v,dist;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&u,&v,&dist);
            u--;v--;
            gr[u][v].push_back(dist);
            gr[v][u].push_back(dist);
        }
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(!gr[i][j].empty()){
                    sort(gr[i][j].begin(),gr[i][j].end());
                    dij.addedge(i,j,gr[i][j][0]);
                    idx[i][j]=dij.m-1;
                    dij.addedge(j,i,gr[i][j][0]);
                    idx[j][i]=dij.m-1;
                }
            }
        }
        ans1=0;
        solve();
        ans2=-1;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(!gr[i][j].empty()){
                    int &e1=dij.edges[idx[i][j]].dist;
                    int &e2=dij.edges[idx[j][i]].dist;
                    if(gr[i][j].size()==1) e1=e2=inf;
                    else e1=e2=gr[i][j][1];
                    ans2=max(ans2,solve_new(i,j));
                    e1=e2=gr[i][j][0];
                }
            }
        }
        cout<<ans1<<" "<<ans2<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值