Uva - 1416 Warfare And Logistics dijkstra维护..题目范围有误..

来源:互联网 发布:山东博达网络 编辑:程序博客网 时间:2024/05/16 08:31

           题意:

                     给了一个无向图...问两两间最短距离之和为多少..当两点不可达时..那么令其距离为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 2505using 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;}


原创粉丝点击