• 【算法每日一练]-图论(保姆级教程 篇4(遍历))#传送门 #负环判断 #灾后重建


    今天继续

    目录

    题目:传送门

    思路:

    题目:负环判断

    思路:

    题目:灾后重建

    思路:


            

                    

            

    题目:传送  门

            

    思路:

            

    先跑一边floyd,然后依次加入每个传送门,O(n^5)不行。

    所以不能跑n^2次floyd,应该单独把两个有影响的点摘出来处理dis,降为O(n^4)能过
            

    1. #include
    2. using namespace std;
    3. const int N=105;
    4. int n,m,f1[N][N],f2[N][N];
    5. inline void back(){
    6. for(int i=1;i<=n;i++)
    7. for(int j=1;j<=n;j++){
    8. f1[i][j]=f2[i][j];
    9. }
    10. }
    11. int main(){
    12. cin>>n>>m;int u,v,w,ans=1e9;
    13. memset(f1,0x3f,sizeof(f1));
    14. for(int i=1;i<=m;i++){
    15. scanf("%d%d%d",&u,&v,&w);
    16. f1[u][v]=w;f1[v][u]=w;
    17. }
    18. for(int k=1;k<=n;k++)
    19. for(int i=1;i<=n;i++)
    20. for(int j=1;j<=n;j++){
    21. f1[i][j]=min(f1[i][k]+f1[k][j],f1[i][j]);
    22. f2[i][j]=f1[i][j];
    23. }
    24. for(int i=1;i<=n;i++)
    25. for(int j=1;j//枚举每个传送门
    26. f1[i][j]=f1[j][i]=0;
    27. for(int k1=1;k1<=n;k1++)
    28. for(int k2=1;k2<=n;k2++)
    29. f1[k1][k2]=min(f1[k1][k2],f1[k1][i]+f1[i][k2]);//由i点进行中转
    30. for(int k1=1;k1<=n;k1++)
    31. for(int k2=1;k2<=n;k2++)
    32. f1[k1][k2]=min(f1[k1][k2],f1[k1][j]+f1[j][k2]);//由i,j点进行中转
    33. int tmp=0;
    34. for(int k1=1;k1<=n;k1++)//这里因为我们没有初始化对角线,所以不要加对角线元素
    35. for(int k2=1;k2//把根据无向图的对称型即可
    36. tmp+=f1[k1][k2];
    37. ans=min(ans,tmp);
    38. back();
    39. }
    40. cout<
    41. return 0;
    42. }

            

            

    题目:负环判断

            

    思路:

            

    只需要记录最短路长度即可,这个长度不是带权的长度,是经过的点个数 如果长度大于n一定有问题,也就是出现了负环,如果不停止就会走向无穷小

            

    1. #include
    2. using namespace std;
    3. const int N=2005,M=3005;
    4. int n,m,tot;
    5. queue<int>q;
    6. int head[N],vis[N],dis[N],cnt[N];//dis存放到每个点的最短距离,cnt存放对应的长度
    7. struct node{int to;int w;int next;}e[M*2];
    8. void add(int u,int v,int w){e[++tot]=(node){v,w,head[u]};head[u]=tot;}
    9. int spfa(){//判断负环的spfa
    10. memset(dis,0x3f,sizeof(dis));
    11. memset(cnt,0,sizeof(cnt));
    12. memset(vis,0,sizeof(vis));
    13. while(!q.empty()) q.pop();//要把队列清空(c++不支持队列清空函数)
    14. dis[1]=0;vis[1]=1;q.push(1);
    15. while(!q.empty()){
    16. int cur=q.front();q.pop();
    17. vis[cur]=0;
    18. for(int i=head[cur];i;i=e[i].next){
    19. int v=e[i].to,w=e[i].w;
    20. if(dis[cur]+w
    21. dis[v]=dis[cur]+w;
    22. cnt[v]=cnt[cur]+1//记录最短路长度;
    23. if(cnt[v]>n)return 1;//如果长度大于n一定有问题,也就是出现了负环,如果不停止就会走向无穷小
    24. if(!vis[v])q.push(v),vis[v]=1;
    25. }
    26. }
    27. }
    28. return 0;
    29. }
    30. int main(){
    31. int t,u,v,w;
    32. cin>>t;
    33. while(t--){
    34. tot=0;memset(head,0,sizeof(head));
    35. cin>>n>>m;
    36. for(int i=1;i<=m;i++){
    37. scanf("%d%d%d",&u,&v,&w);
    38. add(u,v,w);
    39. if(w>=0)add(v,u,w);
    40. }
    41. if(spfa())cout<<"YES"<<'\n';
    42. else cout<<"NO"<<'\n';
    43. }
    44. }

            

            

    题目:灾后重建

             

    思路:

            

    floyd的最外层k其实是在放入前k个点后的对dis的影响

    eg:k为1是仅放入1对dis的影响,k为2是仅放入1和2后对dis的影响,依次类推
    那么此题,我们只需要放一个对应的点,就输出一次,这就是前k个点的影响
            

    1. #include
    2. using namespace std;
    3. const int N=205;
    4. int n,m,INF;
    5. int a[N],f[N][N];
    6. inline void updata(int k){//依次放入k,对各个dis进行影响
    7. for(int i=0;i
    8. for(int j=0;j
    9. if(f[i][j]>f[i][k]+f[k][j])
    10. f[i][j]=f[i][k]+f[k][j];
    11. }
    12. }
    13. int main(){
    14. cin>>n>>m;
    15. for(int i=0;i>a[i];//每个村庄的建好时间
    16. memset(f,0x3f,sizeof(f));INF=f[1][1];//初始化f
    17. for(int i=0;i0;
    18. int u,v,w;
    19. for(int i=1;i<=m;i++){
    20. scanf("%d%d%d",&u,&v,&w);
    21. f[u][v]=f[v][u]=w;
    22. }
    23. int q,t,now=0;cin>>q;
    24. while(q--){
    25. cin>>u>>v>>t;//询问
    26. while(a[now]<=t&&now//把t时间之前的村庄都考虑进去
    27. updata(now);now++;
    28. }
    29. if(a[u]>t||a[v]>t)cout<<-1<<'\n';//村庄还没修好
    30. else{
    31. if(f[u][v]==INF)cout<<-1<<'\n';//根本就无法到达
    32. else cout<'\n';
    33. }
    34. }
    35. return 0;
    36. }

  • 相关阅读:
    基于Docker容器DevOps应用方案
    计算机毕业论文java毕业设计论文题目基于SpringBoot项目源码旅游信息管理系统[包运行成功]
    【业务功能篇104】 补充【业务功能篇99】微服务-springcloud-springboot-电商订单模块--整合支付
    毛绒玩具欧盟CE认证检测标准解析
    (55、56)性能分析命令
    Node.js 21.7.0 发布:内置彩色文本输出、环境变量功能增强、crypto 增加新 hash 方法...
    【广州华锐互动】VR虚拟仿真技术为航测实践教学提供了哪些帮助?
    【Spring Cloud】Nacos 配置管理详解
    一文搞懂临床预测模型的评价
    Android C++系列:Linux文件IO操作(一)
  • 原文地址:https://blog.csdn.net/m0_69478376/article/details/134358487