uestc oj 1876 聚会

下面是我编写的代码,SPFA算法的时间复杂度比较优越。需要用到一个队列,但不同的是,元素入队后可能会再次入队。

SPFA算法用队列来保存可能做松弛操作的节点。
初始时所有点d[]值置INF,源点d[s]为0。将源点放进队列。
当队列不为空时每次从队列中取出队首节点,对该节点发出的每条边进行松弛。将松弛后d[]值改变并且不在队列中的点加入队列。

1.首先初始化 2然后每次取对头元素进行松弛3若产生作用端点不在队列中则加入队列。

vis的作用是用来存储对象是否在队列之中的

本题是一个单行道有向图的(虽说道路一般都是无向的)


/*这个题目点的数量可以达到100000 而边的数量最多不过100000
 属于稀疏矩阵,并且如果采用矩阵存储的话会超内存,并且O(n^2)
 的时间复杂度也是伤不起的,采用前向星存储以节省空间
 采用spfa算法来节省时间O(ke),题目思路用逆向思维,
 求每个人到第一个人的最短路之和
 其实就是求第一个人到每个人的单源最短路径之和(是一个无向图)*/
 
 
 
 
#include<cstdio>
#include<vector>
#include<queue>
#define MAXN 100005
using namespace std;


struct edge
{
    int start,end;
    int val;
};
int n,m,i,j,a,b,w;
vector<edge> v[MAXN];
int dis[MAXN];
bool visited[MAXN];


void spfa()
{
    for(i=1;i<=n;i++)
    {
        dis[i] = MAXN;
        visited[i] = false;
    }
    queue<int>Q;
    dis[1] = 0;  //没问题的  这里已经设置为0
    Q.push(1);
    while(!Q.empty())
    {
        int temp = Q.front();
        Q.pop();
        for(unsigned i=0;i<v[temp].size();i++)
        {
            if(dis[temp] + v[temp][i].val < dis[v[temp][i].end])
            {
                dis[v[temp][i].end] = dis[temp] + v[temp][i].val;
                if(visited[v[temp][i].end]==false)
                {
                    Q.push(v[temp][i].end);
                    visited[v[temp][i].end]= true;
                }


            }
        }
        visited[temp] = false;
    }
}


int main()
{
   //freopen("1.txt","r",stdin);
   while(scanf("%d%d",&n,&m)==2)
   {
       for(i=0;i<m;i++)
       {
           scanf("%d%d%d",&a,&b,&w);
           edge temp;
           temp.start = b;
           temp.end   = a;
           temp.val   = w;
           v[b].push_back(temp);
       }
       spfa();
       int sum = 0;
       for(i=2;i<=n;i++)
       {
          sum+=dis[i];
       }
       printf("%d\n",sum);
   }




   return 0;
}



聚会

party.pas/c/cpp

1s/64MB

 

【题目描述】

n个人打算一起聚会,聚会的地点定在第一个人家里,现在除了第一个人已经在家之外其他人都不在第一个人家里,求n个人到第一个人家里的最短路径长度总和。

【输入】

输入第一行包含两个数n, m,表示人数和以及连通这个n人所在位置的道路数。

接下来的m行每行有3个数ai, bi, wi,表示第i条道路是从第ai个人所在位置指向第bi个人所在位置的单行道,长度为wi。

【输出】

输出一个整数,n个人的最短路径总长度。

【输出样例】

4 4

2 1 1

3 1 2

4 3 2

3 4 1

【输出样例】

7

【数据规模】

对于第0-3组测试数据,n<=100,m<=150

对于第4-7组测试数据,n<=1000,m<=1500

对于第8-9组测试数据,n<=100000,m<=100000





完成情况(cena测评)



这一题虽说是从各个点到一个点,但是我们可以反过来想一下,我们把所有的边都反向,然后求从1到所有点的最短路就和原问题一样了


C++ AC Code

  1. /*http://blog.csdn.net/jiangzh7 
  2. By Jiangzh*/  
  3. #include<cstdio>  
  4. #include<cstring>  
  5. #include<queue>  
  6. #include<utility>  
  7. using namespace std;  
  8. const int N=100000+10;  
  9.   
  10. int n,m;  
  11. struct link{int y,z;link *next;}*head[N];  
  12. typedef pair<int,int> pii;  
  13. priority_queue<pii> Q;  
  14. int dist[N];  
  15. bool h[N];  
  16.   
  17. void inlink(int x,int y,int z)  
  18. {  
  19.     link *node=new link;  
  20.     node->y=y;node->z=z;  
  21.     node->next=head[x];  
  22.     head[x]=node;  
  23. }  
  24.   
  25. void read()  
  26. {  
  27.     freopen("party.in","r",stdin);  
  28.     freopen("party.out","w",stdout);  
  29.     scanf("%d%d",&n,&m);  
  30.     for(int i=1;i<=m;i++)  
  31.     {  
  32.         int x,y,z;  
  33.         scanf("%d%d%d",&x,&y,&z);  
  34.         inlink(y,x,z);  
  35.     }  
  36. }  
  37.   
  38. void work()  
  39. {  
  40.     memset(dist,0x3f,sizeof(dist));  
  41.     dist[1]=0;Q.push(make_pair(0,1));  
  42.     while(!Q.empty())  
  43.     {  
  44.         pii u=Q.top();Q.pop();  
  45.         int k=u.second;  
  46.         if(h[k]) continue;  
  47.         h[k]=true;  
  48.         for(link *node=head[k];node;node=node->next)  
  49.         if(dist[node->y]>dist[k]+node->z)  
  50.         {  
  51.             dist[node->y]=dist[k]+node->z;  
  52.             Q.push(make_pair(-dist[node->y],node->y));  
  53.         }  
  54.     }  
  55.     int res=0;  
  56.     for(int i=1;i<=n;i++) res+=dist[i];  
  57.     printf("%d\n",res);  
  58. }  
  59.   
  60. int main()  
  61. {  
  62.     read();  
  63.     work();  
  64.     return 0;  
  65. }  
  66.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
互联网络程序设计是指在互联网上进行程序开发和设计的过程。UESTC则是我国的一所著名高校——电子科技大学。 互联网络程序设计 uestc包含了两个主要的方面:互联网络和程序设计。互联网络是指将多个计算机网络通过通信链路互相连接起来,实现信息共享和资源共享的网络系统。程序设计是指根据需求和目标,通过编写代码和设计算法,实现计算机程序的过程。 互联网络程序设计 uestc的学习内容主要包括以下几个方面: 1. 网络知识:学习互联网络的基本概念、原理和协议,如TCP/IP协议、HTTP协议等。掌握网络编程的基本技术,能够编写网络应用程序。 2. 数据通信:学习数据通信的基本原理和技术,包括数据传输的方式、数据压缩和加密等。了解网络安全和数据保护的基本知识。 3. 程序设计:学习编程语言和开发工具,如Java、C++和Python等。掌握常用的编程技巧和方法,能够设计和实现复杂的网络应用程序。 4. Web开发:学习Web开发的基本知识和技术,包括HTML、CSS、JavaScript等。能够设计和实现交互式的Web应用程序。 5. 数据库技术:学习数据库的基本原理和技术,如SQL语言和数据库管理系统。能够设计和管理数据库,实现数据的存储和检索。 通过学习互联网络程序设计 uestc,可以掌握互联网应用开发的基本技能,具备设计和实现网络应用程序的能力。这对于目前互联网行业的人才需求来说是非常重要的,也为学生提供了广阔的就业和创业机会。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值