</pre>1541: There is No Alternative</h2><span class="green">Time Limit: </span>3 Sec <span class="green">Memory Limit: </span>256 MB<span class="green">Submit: </span>259 <span class="green">Solved: </span>67[<a target=_blank href="http://acm.csu.edu.cn/OnlineJudge/submitpage.php?id=1541" target="_blank">Submit</a>][<a target=_blank href="http://acm.csu.edu.cn/OnlineJudge/problemstatus.php?id=1541" target="_blank">Status</a>][<a target=_blank href="http://acm.csu.edu.cn/OnlineJudge/bbs.php?pid=1541" target="_blank">Web Board</a>]</center><h2>Description</h2><div class="content"><p><img alt="" src="http://acm.csu.edu.cn/OnlineJudge/upload/201503/Alternative1.jpg" /> </p></div><h2>Input</h2><div class="content"><p><img width="364" height="43" alt="" src="http://acm.csu.edu.cn/OnlineJudge/upload/201503/Alternative2.jpg" /> <img width="750" height="642" alt="" src="http://acm.csu.edu.cn/OnlineJudge/upload/201503/Alternative3.jpg" /></p></div><h2>Output</h2><div class="content"><p> <img width="758" height="71" alt="" src="http://acm.csu.edu.cn/OnlineJudge/upload/201503/Alternative4.jpg" /></p></div><h2>Sample Input</h2><pre class="content"><span class="sampledata">4 4
1 2 3
1 3 3
2 3 3
2 4 3</span>
</pre>1541: There is No Alternative</h2><span class="green">Time Limit: </span>3 Sec <span class="green">Memory Limit: </span>256 MB<span class="green">Submit: </span>259 <span class="green">Solved: </span>67[<a target=_blank href="http://acm.csu.edu.cn/OnlineJudge/submitpage.php?id=1541" target="_blank">Submit</a>][<a target=_blank href="http://acm.csu.edu.cn/OnlineJudge/problemstatus.php?id=1541" target="_blank">Status</a>][<a target=_blank href="http://acm.csu.edu.cn/OnlineJudge/bbs.php?pid=1541" target="_blank">Web Board</a>]</center><h2>Description</h2><div class="content"><p><img alt="" src="http://acm.csu.edu.cn/OnlineJudge/upload/201503/Alternative1.jpg" /> </p></div><h2>Input</h2><div class="content"><p><img width="364" height="43" alt="" src="http://acm.csu.edu.cn/OnlineJudge/upload/201503/Alternative2.jpg" /> <img width="750" height="642" alt="" src="http://acm.csu.edu.cn/OnlineJudge/upload/201503/Alternative3.jpg" /></p></div><h2>Output</h2><div class="content"><p> <img width="758" height="71" alt="" src="http://acm.csu.edu.cn/OnlineJudge/upload/201503/Alternative4.jpg" /></p></div><h2>Sample Input</h2><pre class="content"><span class="sampledata">4 4
1 2 3
1 3 3
2 3 3
2 4 3</span>
Sample Output
1 3
题意:要求构造最小生成树的边中,哪些边是必需的(即删去这条边再构造最小生成树得出的总权值发生了改变),并输出这些边的数目和总权值。
思路:先构造最小生成树,记录总权值sumWeight和使用的边的下标(存入数组used[]),再依次去掉每条边,重新构造最小生成树(注意初始化),比较每次构造的最小生成树的总权值weight,如果与sumWeight不相等,则表示该边不能去掉。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> int flag[55000], n, used[55000]; struct node { int s, d, c; }road[55000]; bool cmp(const node& a, const node& b) { return a.c<b.c; } void init() { for(int i=1; i<=n; i++) flag[i]=i; //初始化根节点为其本身的下标 } int find(int x)//找该点所属的集合的根节点 { return x==flag[x] ? x : flag[x]=find(flag[x]); } using namespace std; int main() { #ifdef OFFLINE freopen("t.txt","r",stdin); #endif int m, i, j; scanf("%d %d", &n, &m); i=1; j=m; while(j--){ scanf("%d %d %d", &road[i].s, &road[i].d, &road[i].c); i++; } sort(road+1, road+i, cmp); //按权值小到大排序 init(); int num=0, sumWeight=0, p=1, L, R; for(i=1; i<=m; i++){ L=find(road[i].s), R=find(road[i].d); if(L != R){ //分属两个不同连通分量 used[p++]=i; //记录第一次构造最小生成树的边下标 flag[L]=R; //改变L的根节点即合并两个集合 num++; //统计已加入边的数目 sumWeight+=road[i].c; } if(num==n-1) break; } int cost=0, weight=0, Num=0; for(i=1; i<p; i++){ //依次减去一条边重新构造最小生成树 weight=0, num=0, init(); //初始化 for(j=1; j<=m; j++){ if(j != used[i]){ L=find(road[j].s), R=find(road[j].d); if(L != R){ num++; flag[L]=R; weight+=road[j].c; } if(num==n-1) break; } } if(sumWeight != weight){//不相等说明该边不能省去 Num++, cost+=road[used[i]].c;//加该边权值(注意该条边下标是used[i]) } } printf("%d %d\n", Num, cost); return 0; }