Aoj-2249

    xiaoxiao2021-03-25  102

    今天看了刘哲大神的博客,真的写的很好啊;

    题意:要首都(原点)和城市之间修路,有两个要求:1每个城市之间都有一组线连接他们(不用直接相连,这点很重要。)2每个城市和首都的最短路不能动;

    这就决定了这道题是最短路而不是最小生成树,因为最小生成树达不到第二个条件,虽然他肯定是能达到第一个条件的 qrz;

    并且第二个要求的情况就是松弛时 相等的情况;

    方法1:可以用spfa,当相等的时候来得到最小的花费,然后把cost相加,

      2:用优化过的dijkstra也可以,不过那个需要看一点优先队列的相关知识,我一会再写写再发一篇好了。

    代码如下:#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn=20005; bool used[maxn]; long long  d[maxn]; int n,m; int len; struct Tree{    int to;   int from;   int value;   int next;   int cost; }tree[maxn*2];//我开始忘记乘以2了,老是tle,re之类的,所以这个一定要注意, int head[maxn]; long long  cost[maxn]; void add(int u,int v,int c,int d) {   tree[len].from=u;    tree[len].to=v;     tree[len].value=c;     tree[len].next=head[u];     tree[len].cost=d;     head[u]=len++; } void init() {  memset(head,-1,sizeof(head));    len=0;    memset(cost,0x3f,sizeof(cost)); } int spfa() {  queue<int>q; //int sum=0;    memset(d,0x3f,sizeof(d));    memset(used,false,sizeof(used));   // d[0]=0;这个没用,因为肯定用不到0点。    cost[0]=0;    while(!q.empty()) q.pop();//这个也没啥用,    used[1]=true;    q.push(1);    d[1]=0;    cost[1]=0;     while(!q.empty())     {    //ceshi=false;         int u=q.front();        used[u]=false;        q.pop();         for(int i=head[u];i!=-1;i=tree[i].next)         {    int  s=tree[i].to;               int w=tree[i].cost;             if(d[s]>d[u]+tree[i].value)               {   if(!used[s])                      {used[s]=true;//可以记录进出队列的次数判断是否存在负环;                       q.push(s);                      }                   d[s]=d[u]+tree[i].value;                   cost[s]=w;                   }                else if(d[s]==d[u]+tree[i].value)//在最短路不变的情况下求最小的距离;                   {  if(cost[s]>w)                       cost[s]=w;                   }         }         //q.pop();     }     for(int i=1;i<=n;i++)        cost[0]+=cost[i];        printf("%lld\n",cost[0]); return 0; } int main() {   int a,b,c,d;      while(~scanf("%d%d",&n,&m),m+n)     {   init();         for(int i=1;i<=m;i++)      {   scanf("%d%d%d%d",&a,&b,&c,&d);          add(a,b,c,d);          add(b,a,c,d);      }      spfa();      //printf("%d\n",spfa());     } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-24806.html

    最新回复(0)