zoukankan      html  css  js  c++  java
  • 100078D Domestic Networks

    传送门

    题目大意

    有两种染料,给定它们的单价和数量,每染色一米需耗费一个单位的染料,一条边只能用一种燃料,给你一张图,要求你将其中的一些边染色使得在满足图联通的情况下花费最小并输出方案。

    分析

    首先,要求图联通且花费最小我们不由想到了求最小生成树,在求完之后我们的问题就变成的看每条边要被染成哪种颜色。我们用dpij表示考虑了前i条边,第一种染料(5号染料)用的数量,并用数组记录一下在这种情况下所选的染料种类就可以了,详见代码。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define sp cout<<"---------------------------------------------------"<<endl
    const int inf=0x3f3f3f3f;
    struct node {
          int x,y,z,id;
    }d[10002];
    int dp[1002][10002],pre[1002],p5,q5,p6,q6,n,m,wh[1002],fa[1002],cnt,tot;
    bool ch[1002][10002];
    struct ans {
          int a,b;
    }out[10010];
    bool cmp(const node a,const node b){return a.z<b.z;}
    bool cmp2(const ans a,const ans b){return a.a<b.a;}
    inline int sf(int x){return fa[x]==x?x:fa[x]=sf(fa[x]);}
    int main(){
          freopen("domestic.in","r",stdin);
          freopen("domestic.out","w",stdout);
          int i,j,k;
          scanf("%d%d",&n,&m);
          for(i=1;i<=m;i++){
            scanf("%d%d%d",&d[i].x,&d[i].y,&d[i].z);
            d[i].id=i;
          }
          scanf("%d%d%d%d",&p5,&q5,&p6,&q6);
          sort(d+1,d+m+1,cmp);
          for(i=1;i<=n;i++)fa[i]=i;
          for(i=1;i<=m;i++){
              if(sf(d[i].x)!=sf(d[i].y)){
                fa[sf(d[i].x)]=sf(d[i].y);
                cnt++;
                pre[cnt]=pre[cnt-1]+d[i].z;
                wh[cnt]=i;
            }
            if(cnt==n-1)break;
          }
          if(cnt<n-1){
              puts("Impossible");
              return 0;
          }
          memset(dp,0x3f,sizeof(dp));
          dp[0][0]=0;
          for(i=1;i<=cnt;i++)
            for(j=0;j<=min(q5,pre[i]);j++){
              if(pre[i]-j>=d[wh[i]].z&&pre[i]-j<=q6)
                dp[i][j]=dp[i-1][j]+d[wh[i]].z*p6;
              if(j>=d[wh[i]].z&&dp[i][j]>dp[i-1][j-d[wh[i]].z]+d[wh[i]].z*p5){
                dp[i][j]=dp[i-1][j-d[wh[i]].z]+d[wh[i]].z*p5;
                ch[i][j]=1;
              }
            }
          int ans=inf,pl;
          for(i=0;i<=q5;i++){
            if(dp[cnt][i]<ans){
              ans=dp[cnt][i];
              pl=i;
            }
          }
          if(ans==inf)puts("Impossible");
            else {
              cout<<ans<<endl;
              for(i=cnt;i>0;i--)
                if(ch[i][pl]){
                  cout<<d[wh[i]].id<<' '<<5<<endl;
                  pl-=d[wh[i]].z;
                }else cout<<d[wh[i]].id<<' '<<6<<endl;
            }
          return 0;
    }
  • 相关阅读:
    安装插件 YouCompleteMe 成功却无法自动补全C++的解决办法
    Ubuntu 16.04 使用 vim_plug 安装插件 YouCompleteMe 报错“ycmd server SHUT DOWN”
    POJ #1062 昂贵的聘礼 有限制的最短路 枚举+dijkstra求最短路
    POJ #3259 Wormholes 判负环 SPFA
    POJ #1860 Currency Exchange 最短路径算法 Bellman-ford SPFA 判断负环
    spfa 算法模板 可求带负权边的最短路 判断负环
    POJ #1042 Gone Fishing 贪心
    路人甲
    Perface
    1. Perface
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9338663.html
Copyright © 2011-2022 走看看