备战快速复习--day13

Bellman Ford

进行n-1轮(最多n-1层,就是[0,n-2]),每次将所有的边松弛,如果进行之后还能松弛,说明是负环

这个复杂度是O(VE),dijkstra是O(V^2+E)

  • 使用邻接表而不是邻接矩阵,邻接矩阵复杂度会上升
  • 邻接表在使用边的时候,判断好Adj[u][j]是对应的边,d[Adj[u][j].v]是对应边终点的d,中间距离dis是Adj[u][j].dis,这段容易搞错
  • 使用set要用insert,因为多轮松弛肯定会多次反复访问重复点,因此要用set
  • 在相等的时候,num的修改就是清零重新计算。(这个也导致不能存完pre等结束以后全部重新计算)
  • 初始num[st]=1;
#include<stdio.h>
#include<string.h>
#include<set>
#include<vector>
using namespace std;
int n,m,st,ed;
const int INF=10000;
int d[1000],w[1000],num[1000];//w代表累计,num是路径数
set<int>pre[1000];
int weight[1000]={0};
struct Node{
    int v;
    int dis;
    Node(int tempv,int tempdis)
    {
        v=tempv;
        dis=tempdis;
    }
};
vector<Node>Adj[1000];
void Bellman(int st)
{
    fill(d,d+n,INF);
    memset(num,0,sizeof(num));
    for(int i=0;i<=n-1;i++)
        w[i]=weight[i];
    /*memset(w,0,sizeof(w));
    w[st]=weight[st];*/
    d[st]=0;
    num[st]=1;
    for(int i=0;i<n-1;i++)
    {
        for(int u=0;u<=n-1;u++)
        {
            for(int j=0;j<Adj[u].size();j++)
            {
                int temp=Adj[u][j].v;
                if(d[temp]>d[u]+Adj[u][j].dis)
                {
                    pre[temp].clear();
                    pre[temp].insert(u);
                    w[temp]=w[u]+weight[temp];
                    d[temp]=d[u]+Adj[u][j].dis;
                }
                else if(d[temp]==d[u]+Adj[u][j].dis)
                {
                    pre[temp].insert(u);
                    w[temp]=max(w[temp],(w[u]+weight[temp]));
                    set<int>::iterator it=pre[temp].begin();
                    num[temp]=0;
                    for(it=pre[temp].begin();it!=pre[temp].end();it++)
                    {
                        num[temp]+=num[*it];
                    }
                }
            }
        }
    }
}
int main()
{
    scanf("%d %d %d %d",&n,&m,&st,&ed);
    for(int i=0;i<=n-1;i++)
        scanf("%d",&weight[i]);
    for(int i=1;i<=m;i++)
    {
        int temp1,temp2,temp3;
        scanf("%d %d %d",&temp1,&temp2,&temp3);
        Adj[temp1].push_back(Node(temp2,temp3));
        Adj[temp2].push_back(Node(temp1,temp3));
    }
    Bellman(st);
    printf("%d %d",num[ed],w[ed]);
    return 0;
}
View Code

 A1003的代码。

猜你喜欢

转载自www.cnblogs.com/tingxilin/p/12483870.html
今日推荐