| ||||||||||
Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Re:此题很有问题.....用kruscal做的,不用sort就AC...加上sort就RE....In Reply To:此题很有问题.....用kruscal做的,不用sort就AC...加上sort就RE.... Posted by:leezy at 2009-04-06 16:24:58 > 附代码: > #include<cstdio> > #include<climits> > #include<queue> > #include<vector> > #include<algorithm> > using namespace std; > const int N=207; > int max_[N][N]; // 最小权边邻接点集合,最小权边值集合 > struct edge { // 边信息 > int u,v,w; > friend bool operator<(edge const&L,edge const&R) { > return L.w<R.w; > } > } ; > struct edge_ { > int v,w; > edge_(int x,int y ) { > v = x; w = y; > } > }; > vector<edge_> ve[N]; > edge E[N*N]; > bool e[N]; > class UF { // 并查集 > public: > void makeset(int i ) { parent[i] = i; rank[i] = 0; } > void Union(int x,int y) { link(Find(x),Find(y)); } > int Find(int x) { > if(parent[x]!=x) parent[x] = Find(parent[x]); > return parent[x]; > } > bool Joint(int x,int y){ return Find(x)==Find(y); } > private: > int parent[N],rank[N]; > void link(int x,int y) { > if(rank[y]<rank[x]) { > parent[y] = x; > } > else { > parent[x] = y; > if(rank[x]==rank[y]) ++rank[y]; > } > } > }; > int kruscal(edge*E,int n,int m) > { > UF uf; > for(int i=1;i<=n;++i) uf.makeset(i); > for(int i=0;i<m; ++i) e[i]=false;; > std::sort(E,E+m); > int sum = 0; > for(int i=0,j=0;i<m&&j<n-1;++i) { > int x=E[i].u; > int y=E[i].v; > if(!uf.Joint(x,y)) { > sum += E[i].w; > uf.Union(x,y); > ve[x].push_back(edge_(y,E[i].w)); > ve[y].push_back(edge_(x,E[i].w)); > e[i] = true; > ++j ; > } > } > return sum; > } > void getmax_(int u,int n) > { > memset(max_[u],0xff,sizeof(max_[u])); > queue<int> Q; > Q.push(u); > while( !Q.empty() ) { > int v = Q.front() ; Q.pop(); > for(int i=0;i<(int)ve[v].size();++i) > { > edge_ const &x = ve[v][i]; > if(max_[u][x.v]==-1&&x.v!=u) { > if(u==v|| x.w>max_[u][v]) max_[u][x.v] = x.w; > else max_[u][x.v] = max_[u][v]; > Q.push(x.v); > } > } > } > } > int mst_sec(edge*E,int n,int m,int sum) > { > for(int i=1;i<=n;++i) getmax_(i,n); // 求树上任意两点间的最大边权? > int mx=INT_MAX; > for(int i=0;i<m;++i) { > if( e[i] == false ) { > if(mx>E[i].w-max_[E[i].u][E[i].v]) > mx=E[i].w-max_[E[i].u][E[i].v]; > } > } > return sum - mx; > } > int main() > { > int n,m,test; > scanf("%d",&test); > for( ; test ; --test) > { > scanf("%d%d",&n,&m); > for(int i=0;i<m;++i) > { > int a,b,w; > scanf("%d%d%d",&a,&b,&w); > E[i].u = a; E[i].v = b; E[i].w = w; > } > int res = kruscal(E,n,m); > if(res == mst_sec(E,n,m,res)) printf("Not Unique!\n"); > else printf("%d\n",res); > for(int i =1;i<=n;++i) ve[i].clear(); > } > return 0; > } Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator