2月19号学习日记

上午:
9:00-9:05 日常签到;  
9:05-12:15 看数据结构与算法慕课网课(看完第三章线性表);
下午:
12:30-15:00 看数据结构与算法慕课网课(第四章树);
16:00-19:00 刷题(拓扑排序);

今天回顾了之前学过的一些数据结构与算法,对于栈与队列,二叉树有了系统的认知(可能是之前学得比较零散),刷题的时候学会了解决多权值的最短路径问题,拓扑排序。

栈和队列用于解决有特定顺序的线性表问题,栈是先进后出,队列是先进先出,可以用链表实现也可以用数组模拟,为了提高使用率还可以用循环链表。后缀表达式的求值就是栈的一个很好的应用,当表达式里出现括号时要注意其优先级最高,只有遇到右括号时左括号才会出栈。多权值的最短路径问题https://vjudge.net/contest/357138#problem/C哇,读到这个题,心想求最短路径和最小花费,直接两边DijkstraOK,直接WA。后来想想,先要保证路径最短,那么就先求最短路径,Dijkstra不变,只不过最后更新的时候处理一下最小花费就行了,具体处理方法见代码。另外,既然存在路径相同而花费不同,那么必然输入数据存在两顶点相同,路径相同,但花费不同的数据,所以输入的时候我们只保留相同情况下花费最小即可。

void dijkstra(int start)
{
 for(int i=1;i<=n;i++)
 {
  dis[i]=map[start][i];
  v[i]=value[start][i];
  book[i]=0;
 }
 book[start]=1;
 for(int i=1;i<=n;i++)
 {
  int min=INF,k;
  for(int j=1;j<=n;j++)
     if(!book[j]&&dis[j]<min)
        min=dis[k=j];
  book[k]=1;
  for(int j=1;j<=n;j++)
  {
   if(dis[j]>dis[k]+map[k][j])
      {
       dis[j]=dis[k]+map[k][j];
          v[j]=v[k]+value[k][j];
   } 
      else if(dis[j]==dis[k]+map[k][j]&&v[j]>v[k]+value[k][j])
          v[j]=v[k]+value[k][j]; 
  }   
 }
}
int main()
{
    int a,b,c,p,m;
    while(cin>>n>>m)
 {
        if(m==0&&n==0)
   break;
        memset(map,INF,sizeof(map));
        memset(value,INF,sizeof(value));
        for(int i=0;i<m;i++)
  {
            cin>>a>>b>>c>>p;
            if(c<map[a][b])
   {
                map[a][b]=map[b][a]=c;
                value[a][b]=value[b][a]=p;
            }
            if(c==map[a][b]&&value[a][b]>p)
                value[b][a]=value[a][b]=p;
        }
  int s,t;
        scanf("%d%d",&s,&t);
        dijkstra(s);
        printf("%d %d\n",dis[t],v[t]);
    }
} 

拓扑排序:在一个有向图中,对所有的节点进行排序,要求没有一个节点指向它前面的节点。先统计所有节点的入度,对于入度为0的节点就可以分离出来,然后把这个节点指向的节点入度减一,直到所有节点都被分离出来。

void topsort(int v)
{
 for(int i=1;i<=v;i++)
    for(int j=1;j<=v;j++)
       if(map[i][j])
         rudu[j]++;
 int k;
 for(int i=1;i<=v;i++)
 {
  for(int j=1;j<=v;j++)
  {
   if(rudu[j]==0)
   {
    k=j;
    break;
   }
  }
  path[i]=k;//存入数组稍后输出
  rudu[k]=-1;//入度为0,存入数组后将其赋为-1
  for(int j=1;j<=v;j++)//遍历,将与其相关的节点入度减一
  {
   if(map[k][j])
     rudu[j]--;
  }
 }
}
发布了32 篇原创文章 · 获赞 5 · 访问量 906

猜你喜欢

转载自blog.csdn.net/LebronGod/article/details/104400042