[最小环 最小环计数 最大平均环 模板题] POJ 1734 Sightseeing trip & FZU 2090 旅行社的烦恼 & POJ 2949 Word Rings

poj1734 最小环路径

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;  

const int N=105;  
const int oo=1<<29;  

int n,m,Ans;    
int w[N][N],f[N][N],pre[N][N];  
int pnt,lst[N];    

inline void dfs(int i,int j){  
  int k=pre[i][j];  
  if (k==0) return void(lst[++pnt]=j);
  dfs(i,k); dfs(k,j);  
}  

inline void Floyd(){  
  Ans=oo; cl(pre);
  for (int k=1;k<=n;k++){
    int x=0,y=0;
    for (int i=1;i<=n;i++) 
      for (int j=1;j<=n;j++){
    if (i==k || j==k || i==j) continue; 
    if (f[i][j]+w[i][k]+w[k][j]<Ans)
      x=i,y=j,Ans=f[i][j]+w[i][k]+w[k][j];
      }
    if (x && y)
      pnt=0,lst[++pnt]=x,dfs(x,y),lst[++pnt]=k;  
    for (int i=1;i<=n;i++)
      for (int j=1;j<=n;j++)
    if (f[i][k]+f[k][j]<f[i][j])  
      f[i][j]=f[i][k]+f[k][j],pre[i][j]=k;  
  }  
}  

int main(){
  freopen("t.in","r",stdin);
  freopen("t.out","w",stdout);
  int iu,iv,iw;
  while(~scanf("%d%d",&n,&m)){  
    for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) w[i][j]=f[i][j]=oo;  
    for (int i=1;i<=n;i++) w[i][i]=f[i][i]=0; 
    for (int i=1;i<=m;i++){    
      scanf("%d%d%d",&iu,&iv,&iw);
      w[iu][iv]=w[iv][iu]=f[iu][iv]=(f[iv][iu]=min(f[iv][iu],iw));
    }  
    Floyd();  
    if (Ans==oo)  
      puts("No solution.");  
    else{  
      for (int i=1;i<=pnt;i++) printf("%d ",lst[i]);
      printf("\n");
    }  
  }  
  return 0;  
}  

fzu2090 最小环计数

还以为多高大上 求出最小环 然后和之前的比较更新一下就可以了
不过对于每个 k 枚举i j 时 要i<k j<k
这样每个环在编号最大的点上被计一次

poj2949 最大平均环

二分答案 给每条边减去一个值 然后跑SPFA看看是不是有正环 又是暴力233

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值