zoukankan      html  css  js  c++  java
  • poj3422K方格取数——最大费用最大流

    题目:http://poj.org/problem?id=3422

    最大费用最大流:

    拆点,在自点之间连两条边,一条容量为1,边权为数字;一条容量为k-1,边权为0;表示可以走k次,只有一次能取到数字;

    从每个格子能向下或向右走,于是向下面的点、右面的点连边;

    将E-K算法中的bfs改成spfa求最长路(边权最大),找出最大流即为答案;

    因为对E-K算法不太熟练,WA了n遍,最后发现是不能像dinic一样在bfs中途找到汇点就退出,因为不是构建分层图,而是spfa求最长路。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    queue<int>q;
    int n,k,ans,head[5005],ct=1,s,t,inf=1e9,dis[5005],pre[5005],incf[5005];
    bool vis[5005];
    struct N{
        int to,next,w,v;
        N(int t=0,int n=0,int ww=0,int vv=0):to(t),next(n),w(ww),v(vv) {}
    }edge[25005];
    void add(int x,int y,int ww,int vv)
    {
        edge[++ct]=N(y,head[x],ww,vv);head[x]=ct;
        edge[++ct]=N(x,head[y],0,-vv);head[y]=ct;
    }
    bool bfs()
    {
        memset(vis,0,sizeof vis);
        memset(pre,0,sizeof pre);
        memset(dis,-1,sizeof dis);
        memset(incf,2,sizeof incf);
        while(q.size())q.pop();
        q.push(s);vis[s]=1;dis[s]=0;
        while(q.size())
        {
            int x=q.front();q.pop();vis[x]=0;
            for(int i=head[x];i;i=edge[i].next)
            {
                int u=edge[i].to;
    //            if(vis[u])continue;
                if(edge[i].w&&dis[u]<dis[x]+edge[i].v)//残量网络spfa
                {
                    dis[u]=dis[x]+edge[i].v;
                    incf[u]=min(edge[i].w,incf[x]);
                    pre[u]=i;
                    if(!vis[u])q.push(u),vis[u]=1;
    //                if(u==t)return 1;//!!!
                }
            }
        }
        if(dis[t]<0)return 0;
        else return 1;
    //    return 0;
    }
    void up()
    {
        int x=t;
        while(x!=s)
        {
            int i=pre[x];
            edge[i].w-=incf[t];
            edge[i^1].w+=incf[t];
            ans+=edge[i].v*incf[t];//
            x=edge[i^1].to;
        }
    //    ans+=dis[t]*incf[t];// 皆可 
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                int x,p=(i-1)*n+j,p2=p+n*n;
                scanf("%d",&x);
                add(p,p2,1,x);
                add(p,p2,k-1,0);//
                if(i<n)add(p2,p+n,k,0);
                if(j<n)add(p2,p+1,k,0);
            }
        s=0;t=2*n*n+1;
        add(s,1,k,0);
        add(2*n*n,t,k,0);
        while(bfs())up();
        printf("%d",ans);
        return 0;
    }

    附数据:

    20 8
    851 28 749 733 797 281 380 553 820 362 913 416 997 11 821 693 200 977 392 843
    981 899 200 889 849 120 223 427 349 165 570 146 288 526 383 301 868 240 671 991
    807 572 253 962 387 862 725 276 271 990 232 393 87 494 887 314 346 222 238 589
    435 61 395 797 267 553 135 491 316 641 749 429 481 192 496 86 412 164 50 734
    688 600 922 227 528 71 141 647 831 155 528 925 466 965 301 519 562 277 997 897
    703 460 181 355 266 55 643 443 993 887 851 553 641 423 661 327 6 14 697 337
    455 582 758 937 584 172 431 607 247 833 216 199 571 488 407 874 810 193 486 921
    499 349 824 71 387 883 978 375 907 595 700 839 969 441 544 827 382 795 570 133
    529 630 528 539 146 711 44 97 969 142 304 33 512 759 610 864 782 604 120 747
    62 437 237 457 495 402 133 491 437 834 373 249 912 277 230 527 171 927 348 448
    592 709 938 522 66 677 417 355 514 481 664 977 823 517 965 272 912 106 189 447
    771 177 441 884 500 652 642 394 302 289 446 200 661 672 251 988 175 15 700 280
    336 612 674 531 917 467 20 675 772 465 706 217 626 296 246 813 996 907 340 69
    411 141 643 632 225 309 828 32 73 341 715 919 134 131 237 336 130 503 641 602
    155 894 465 945 921 551 435 821 402 860 690 943 585 875 651 337 933 869 581 413
    134 38 200 97 94 143 233 945 389 497 941 69 509 475 973 469 327 653 760 771
    854 133 319 800 898 2 53 217 496 104 677 51 792 147 993 181 230 720 32 605
    838 904 511 637 578 398 291 327 198 203 918 71 782 319 873 352 102 459 841 490
    993 37 77 563 622 828 110 387 160 741 327 796 605 533 512 641 242 984 742 214
    637 153 709 441 987 514 24 776 163 231 648 915 570 894 460 491 184 825 904 707
    
    154093
    
    
    19 10
    520 305 854 266 616 47 266 677 361 204 523 660 807 876 914 565 782 238 639
    266 956 50 797 202 169 835 78 254 770 975 678 327 871 404 348 614 201 93
    470 428 392 277 37 35 892 268 297 980 691 0 974 579 626 190 287 464 559
    465 953 56 182 722 148 723 115 392 5 423 224 802 527 333 911 355 540 442
    418 676 247 297 312 289 435 182 891 925 545 534 800 871 446 30 399 257 811
    233 844 990 481 614 972 965 789 369 20 619 440 849 583 997 426 106 222 870
    448 908 213 750 44 115 364 364 580 832 411 333 605 936 313 782 593 396 391
    246 614 809 792 511 74 600 172 303 348 905 429 306 525 35 177 34 566 815
    690 49 539 566 331 574 545 672 588 535 388 119 239 486 212 755 35 263 473
    791 857 305 301 716 981 411 408 293 791 552 746 306 723 518 972 321 622 780
    728 417 467 346 306 425 701 933 567 449 597 363 366 735 661 123 883 933 430
    25 771 392 111 257 917 556 144 386 382 863 334 622 256 747 951 798 716 560
    8 938 205 426 757 322 639 958 194 287 240 546 295 13 446 494 81 973 337
    670 135 62 42 945 473 180 83 535 80 804 681 598 818 798 272 53 837 908
    110 669 254 658 595 77 834 263 959 206 300 163 965 814 616 977 846 536 560
    711 937 251 94 227 193 986 369 681 384 300 355 218 523 61 690 583 717 949
    805 686 768 887 186 468 145 757 13 588 620 282 307 343 857 968 40 260 405
    923 558 930 539 734 104 68 316 540 774 740 917 882 705 219 488 811 809 167
    462 332 716 606 652 585 10 843 427 823 863 351 164 291 865 993 979 219 379
    
    158617
    数据
  • 相关阅读:
    绘制饼状图
    柱状图使用实例
    柱状图颜色区分
    bar函数与barh函数
    绘制柱状图
    绘制不同样式不同颜色的线
    Windows10没有修改hosts文件权限
    Lucene入门学习
    Kafka学习笔记
    Elasticsearch学习笔记(强推)
  • 原文地址:https://www.cnblogs.com/Zinn/p/8625777.html
Copyright © 2011-2022 走看看