CSU--1541-- There is No Alternative
2015-11-12 14:18
253 查看
</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 OFFLINEfreopen("t.txt","r",stdin);#endifint 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;}
相关文章推荐
- LD_LIBRARY_PATH环境变量的设置
- ConfigurationManager.AppSettings["XXX"] 读取配置文件
- 解决struts2在(IE,Firefox)下载文件名乱码问题
- UNION中ORDER By的使用
- lhgdialog.js弹出框
- 读书分享 分类什么的慢慢来吧
- 网络文件下载
- 新浪也遇寒冬:全面停止社招—兄弟连IT教育
- Android强制设置横屏或竖屏
- 堆排序
- Xamarin
- 二叉树的非递归遍历
- Linux 下的定时任务实现 at 和 crontab
- iOS中Quartz2D
- iOS工程路径,路径宏
- CentOS 配置Tomcat及搭配Nginx
- php用户注册信息验证正则表达式
- Android 实时时间显示实现
- 【转】那些年我们一起清除过的浮动
- Jackson