zoj 1677 Oil Deal 最大生成树 Andrew Stankevich's Contest #8(H)

题目地址: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1677

首先要求最大生成树,来保证图的连通性(基于贪心的思想--尽量炸代价小的路,能炸得更多)  

然后在资金足够的情况下,一一去炸代价小的路,直到钱不够当前最便宜的路了,break掉


代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

int p[50005];

struct edge
{
    int id;
    int x;
    int y;
    int w;

};

edge e[100005];

bool ex[100005];
bool cmp(edge a,edge b)
{
    return a.w>b.w;

}
bool vecmp(edge a,edge b)
{
    return a.id<b.id;

}

int find(int x)
{
   if(p[x]==x)  return x;
   else return p[x]=find(p[x]);

}
int n,m;
int cc;


void kruskal()
{

   for(int i=0;i<n;i++)
     p[i]=i;

    int cc=n;
   for(int i=0;i<m;i++)
     {
         int x=find(e[i].x);
         int y=find(e[i].y);

         if(x!=y)
         {
            ex[i]=1;
            p[x]=y;

            cc--;
            if(cc==1)  break;
         }
     }


}

vector<edge>  ve;

int main()
{


     int flag=0;

     long long s;

     int x,y,w;
     while( cin>>n>>m>>s)
     {

          memset(ex,0,sizeof(ex));

          ve.clear();
          if(flag==1)  cout<<endl;
          if(flag==0)  flag=1;

          for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&x,&y,&w);
                e[i].x=x-1;
                e[i].y=y-1;
                e[i].w=w;
                e[i].id=i;

            }
        sort(e,e+m,cmp);
        kruskal();



        for(int i=m-1;i>=0;i--)
        {
           if(ex[i]==1)  continue;
           if(s<e[i].w)  break;

           ve.push_back(e[i]);
           s-=e[i].w;
        }
      
       cout<<ve.size()<<endl;
       if(ve.size()>0) 
       {
        
       sort(ve.begin(),ve.end(),vecmp);
       for(int i=0;i<ve.size()-1;i++)
        cout<<ve[i].id+1<<" ";

       cout<<ve[ve.size()-1].id+1;
        cout<<endl;
       }

     }


}


posted on 2013-09-13 00:09  814jingqi的ACM  阅读(136)  评论(0编辑  收藏  举报