|
沙发
楼主 |
发表于 2021-5-17 20:30:44
|
只看该作者
我用一个标准的dijkstra 来做这个题,大家看看
- #include<bits/stdc++.h>
- using namespace std;
- const int inf=2147483647;
- const int mm=500050;
- const int mn=10010;
- int n,m,s;
- int nxt[mm],ev[mm],ew[mm];
- int dist[mn],vist[mn],nbs[mn],p[mn],heap[mn];
- int getmin()
- {
- int m,k,i;
- m=inf;
- k=0; ///起点,无路可找的时候就返回0
- ///for (i=1;i<=n;i++) cout<<dist[i]<<' '; cout<<endl;
- for (i=1; i<=n; i++)
- if (!vist[i])
- if (dist[i]<m)
- {
- m=dist[i];
- k=i;
- }
- return k;
- }
- void dijkstra(int src)
- {
- int i,j,u,v,cnt=1;
- for(i=1; i<=n; i++)
- {
- dist[i]=inf;
- vist[i]=0;
- };
- dist[src]=0;
- heap[1]=src;
- while(cnt<=n)
- {
- u=getmin();
- cnt++;
- vist[u]=1;
- for(j=nbs[u]; j!=0; j=nxt[j])
- {
- v=ev[j];
- if(!vist[v]&&dist[u]+ew[j]<dist[v])
- {
- dist[v]=dist[u]+ew[j];
- p[v]=u;
- }
- }
- }
- }
- void printpath(int i)///反推路径找到S到I的路
- {
- int path[mn]= {i,}; ///初始终点
- int j=0,k=i;
- while (p[k]!=0) ///完全类似导弹飞机的倒推
- {
- j++;
- path[j]=p[k];
- k=p[k];
- }
- cout<<s<<"-->"<<i<<':';
- for (; j>=0; j--) cout<<path[j];
- cout<<endl;
- }
- int main()
- {
- int i,u,v,w;
- scanf("%d%d%d",&n,&m,&s);
- for(i=1; i<=n; i++)nbs[i]=0;
- for(i=1; i<=m; i++)
- {
- scanf("%d%d%d",&u,&v,&w);
- nxt[i]=nbs[u];
- nbs[u]=i;
- ev[i]=v;
- ew[i]=w;///这里考虑一下如何去掉重复的边,
- }
- dijkstra(s);
- for (i=1; i<=n; i++) printf("%d ",dist[i]);
- ///cout<<endl;
- ///for (i=1; i<=n; i++) printpath(i);
- return 0;
- }
复制代码
注意此题数据规模比较大,读入输出要用scanf和printf,否则只有70分 |
|