• POJ 3621 01分数规划


    题意:

    给出一个有向图,问求一个回路,使得回路上的点权之和/边权之和最大。

    题解:

    01分数规划,简单构造,将点权转移到边权上~因为一个环上的点和边的数量是相等的~

    设i,j之间初始边权为w[i][j],修改后的边权为g[i][j],则g[i][j]=w[i][j]*mid+val[i]

    spfa判负环即可~

    01分数规划详见:http://www.cnblogs.com/proverbs/archive/2013/01/09/2853725.html

    代码包含bfs版spfa和dfs版spfa两种版本

    dfs版spfa真是快,16ms,在c++里耗时排第一,嘿嘿~

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <algorithm>
      6 #include <cmath>
      7 
      8 #define N 1100
      9 #define M 1000100
     10 
     11 using namespace std;
     12 
     13 int a[M],b[M];
     14 int head[N],next[M],to[M];
     15 int q[M*5],im[N];
     16 int vis[N];
     17 int n,cnt,m,st;
     18 double l,r,mid,c[M],dis[N],len[M],val[N];
     19 
     20 inline void add(int u,int v,double w)
     21 {
     22     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
     23 }
     24 
     25 inline void read()
     26 {
     27     memset(head,-1,sizeof head); cnt=0;
     28     for(int i=1;i<=n;i++) scanf("%lf",&val[i]);
     29     for(int i=1;i<=m;i++)
     30     {
     31         scanf("%d%d%lf",&a[i],&b[i],&c[i]);
     32         add(a[i],b[i],c[i]);
     33     }
     34 }
     35 /*queue版spfa 
     36 inline bool spfa()
     37 {
     38     memset(im,0,sizeof im);
     39     int h=1,t=1,sta;
     40     for(int i=1;i<=n;i++)
     41     {
     42         q[t++]=i;
     43         dis[i]=0.0;
     44         vis[i]=true;
     45         im[i]++;
     46     }
     47     while(h!=t)
     48     {
     49         sta=q[h++]; vis[sta]=false;
     50         for(int i=head[sta];~i;i=next[i])
     51             if(dis[to[i]]>dis[sta]+len[i]*mid-val[sta])
     52             {
     53                 dis[to[i]]=dis[sta]+len[i]*mid-val[sta];
     54                 if(!vis[to[i]])
     55                 {
     56                     vis[to[i]]=true;
     57                     q[t++]=to[i];
     58                     if(++im[to[i]]>n) return true;
     59                 }
     60             }
     61     }
     62     return false;
     63 }
     64 */
     65 
     66 inline bool dfs(int u)
     67 {
     68     vis[u]=st;
     69     for(int i=head[u];~i;i=next[i])
     70         if(dis[to[i]]>dis[u]+len[i]*mid-val[u])
     71         {
     72             dis[to[i]]=dis[u]+len[i]*mid-val[u];
     73             if(vis[to[i]]==st) return true;
     74             else if(dfs(to[i])) return true;
     75         }
     76     vis[u]=0;
     77     return false;
     78 }
     79 //dfs-spfa找负环 
     80 inline bool spfa()
     81 {
     82     memset(vis,0,sizeof vis);
     83     for(st=1;st<=n;st++)
     84         if(dfs(st)) return true;
     85     return false;
     86 }
     87 
     88 inline void go()
     89 {
     90     l=0.0; r=1000.0;
     91     while(r-l>1e-4)
     92     {
     93         mid=(l+r)/2.0;
     94         if(spfa()) l=mid;
     95         else r=mid;
     96     }
     97     printf("%.2lf\n",mid);
     98 }
     99 
    100 int main()
    101 {
    102     while(scanf("%d%d",&n,&m)!=EOF) read(),go();
    103     return 0;
    104 }
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    Flutter TextField 文本输入框的基本属性
    Flutter 之网络请求Dio, FormData, 表单网络请求, x-www-form-urlencoded
    操作DataTable数据,修改某列的值
    获取DataTable某一列所有值
    ajax将数据遍历给select的option选项
    Flutter 获取网络数据及渲染列表
    Flutter实现APP版本更新
    Flutter 一些常用库插件
    flutter_screenutil屏幕適配
    前端组件学习
  • 原文地址:https://www.cnblogs.com/proverbs/p/2853741.html
Copyright © 2020-2023  润新知