关键路径——杭电 4109
来源:互联网 发布:adobereader破解版mac 编辑:程序博客网 时间:2024/06/05 08:57
--------------------------11月23日-------------------------
昨天和今天一直在写一道题,杭电的4109
题目不难,可是我的经验实在是太少了。题目就是一道关键路径的。光把用邻接表求关键路径给写出来就写了两三个小时,然后还修复了两个小错误。提交上去仍然是re。到现在还是没找出来为什么。在数据量小于10的时候可以正常结束。但是一旦数据大于10个了就只是能输出答案,然后就不能正常结束了。
看到别人的博客真心着急啊。别人差不多每天两三道题的速度在往前飞跃,而我却两三天一道题的速度在往前慢慢爬。差距怎么就这么大
下面是这次的代码(这个代码就不用认认真真看了,基本就是数据结构书上面的内容,只是拿出来做一下反例,重点是后面所学到的东西)
#include<iostream>#include<stack>#include<string.h>using namespace std;#define MAXinstr 2000 //the max number of instructions#define ERROR 0;#define OK 1;int ve[MAXinstr],vl[MAXinstr];typedef struct ArcNode{int adjvex;struct ArcNode *nextarc;int info;}ArcNode;typedef struct VNode{int data;ArcNode *firstarc;}VNode,AdjList[MAXinstr];typedef struct {AdjList instruction; //the list of instructionsint vexnum,arcnum;}ALGraph;void FindInDegree(ALGraph G,int indegree[]){ //get indegree of every verticsArcNode *p;for(int i=0;i<G.vexnum;i++){indegree[i]=0;}for(int i=0;i<G.vexnum;i++){for(p=G.instruction[i].firstarc;p;p=p->nextarc){indegree[p->adjvex]++;}}}int TopologicalOrder(ALGraph G,int T[]){int *indegree=(int*)malloc(sizeof(int)*(G.arcnum+10));FindInDegree(G,indegree);int count=0;for(int i=0;i<G.vexnum;++i){ve[i]=0;}int S[MAXinstr];int Snum=0;for(int i=0;i<G.vexnum;++i){if(!indegree[i]){S[Snum]=i;Snum++;}}ArcNode *p;int tmp=0;while(Snum){int j=S[Snum-1];Snum--;T[tmp]=j;count++;for(p=G.instruction[j].firstarc;p;p=p->nextarc){int k=p->adjvex;indegree[k]--;if(!indegree[k]){S[Snum]=k;Snum++;}if(ve[j]+p->info>ve[k])ve[k]=ve[j]+p->info;}//for}//whileif(count<G.vexnum)return 0;return 1;}int CriticalPath(ALGraph G){int T[MAXinstr];if(!TopologicalOrder(G,T))return ERROR;for(int i=0;i<G.vexnum;++i){vl[i]=ve[i];}int tmp=G.vexnum-1;while(tmp>=0){int j=T[tmp];tmp--;ArcNode *p;for(p=G.instruction[j].firstarc;p;p=p->nextarc){int t=p->adjvex;int dut=p->info;if(vl[t]-dut>vl[j])vl[j]=vl[t]-dut;}//for}//while/*for(int i=0;i<G.vexnum;++i){ArcNode *p;for(p=G.instruction[i].firstarc;p;p=p->nextarc){int k=p->adjvex;int dut=p->info;int ee=ve[i];int el=vl[k]-dut;if(ee==el){CPath[CP]=i;CP++;}}}*/return OK;}int CreateALGraph(ALGraph &G,int vertixnum,int arc){G.vexnum=vertixnum;G.arcnum=arc;for(int i=0;i<G.vexnum;++i){G.instruction[i].firstarc=NULL;}for(int i=1;i<=G.arcnum;++i){int j,k,dur;cin>>j>>k>>dur;j--;k--;ArcNode *p;p=G.instruction[j].firstarc;while(p&&p->nextarc)p=p->nextarc;ArcNode *tmp=(ArcNode*)malloc(sizeof(ArcNode));tmp->info=dur;tmp->adjvex=k;if(!p)G.instruction[j].firstarc=tmp;elsep->nextarc=tmp;tmp->nextarc=NULL;}return OK;}int main(){int m,n;cin>>m>>n;ALGraph G;CreateALGraph(G,m,n);CriticalPath(G);int maxCP=0;for(int i=0;i<G.vexnum;++i){if(maxCP<vl[i])maxCP=vl[i];}cout<<maxCP+1<<endl;return 0;}
如果输入像30 0这样的数据,可以正确的输出结果,但是结果输出以后就崩溃了。怎么一个return 0 都这么虐我了0.0
------------------------------11月28日--------------------------------------
对于输入30 0 这样的数据会崩溃的问题,今天终于找到问题的原因了。因为在代码中搞了太多很大很大的数组,而且这些数组都放在了局部变量里面。对于需要用到很大的数组的程序,大数组一定要放在全局变量里面,否则程序就会很莫名其妙的崩溃,就像前几天的我那样……
-------------------------12月1日--------------------------------------------
今天终于把这道题给解决了,而且从中学到了好多东西。
首先是放弃了原来写出来的代码,参考了别人大神的博客 http://blog.csdn.net/kkkwjx/article/details/12257829
这种做法是用邻接矩阵来表示的,没有用邻接表的办法。不过仔细想想,邻接矩阵虽然存储空间会比邻接表大,但是临街矩阵的处理速度就比邻接表快多了,邻接表需要申请空间什么的一大堆东西。
接下来是代码(这个就是可以通过的代码了)
#include<iostream>#include<stdio.h>#include<stack>using namespace std;#define MAXN 1005int g[MAXN][MAXN];int topo[MAXN];int el[MAXN];int main(){int m,n;while(scanf("%d%d",&n,&m)!=EOF){//n instructions,m vertixesmemset(g,0,sizeof(g));memset(el,0,sizeof(el));memset(topo,0,sizeof(topo));int ind[MAXN]={0},Ind[MAXN]={0};int x,y,z;for(int i=0;i<m;++i){scanf("%d%d%d",&x,&y,&z);//第一次写的时候这里用的是cin,为什么改成scanf是有原因的,看下面的分析~~~if(!g[x][y]){g[x][y]=z;ind[y]++;Ind[y]=ind[y];}}stack<int> S;for(int i=0;i<n;++i){if(!ind[i])S.push(i);}int p=0;while(!S.empty()){int gettop=S.top();S.pop();topo[p++]=gettop;for(int i=0;i<n;++i){if(g[gettop][i]){ind[i]--;if(!ind[i])S.push(i);}}}//whileint mx=0;for(int i=0; i<n; ++i) { int pos=topo[i]; if(!Ind[pos])el[pos]=0; else { for(int t=0; t<n; ++t) if(g[t][pos]) el[pos]=max(el[t]+g[t][pos],el[pos]); mx=max(mx,el[pos]); } }cout<<mx+1<<endl;}return 0;}
算法的思想跟邻接表一模一样,可以看得出来用邻接矩阵使代码简洁了快100行
接下来是在做这道题的过程中遇到的东西。
第一次在写这段代码的时候,输入边以及权值的时候,我用的是cin而不是scanf,然后就一直超时,仔仔细细的跟人家的代码对比了几遍都没找出来什么原因,然后就把别人的循环一段一段的往自己的代码上面复制,希望能找到什么原因。一直复制到输入的那个循环的时候终于找到问题了。于是就开始找百度原因。后来知道了原来用scanf函数比用cin要快好多。(用cin的时候运行在1秒以上,而用scanf以后运行时间是260多毫秒,速度差距了将近五倍)。默认情况,cin与stdin总是保持同步的,也就是说这两种方法可以混用,而不必担心文件指针混乱,同时cout和stdout也一样,两者混用不会输出顺序错乱。正因为这个兼容性的特性,导致cin有许多额外的开销,如何禁用这个特性呢?只需一个语句std::ios::sync_with_stdio(false);,这样就可以取消cin于stdin的同步了,此时的cin就与scanf差不多了。(这句话复制了这篇文章中的原话http://hi.baidu.com/i5love1you9/item/2b97cb3dd91f20b7134b14c5)
到今天为止这道题终于算是完成了,从这道题中可以学到两点做算法题目的时候的技巧,首先,在开数组的时候,如果数组空间比较大,那么就要把数组声明为全局变量,要不然程序很容易就崩溃了。第二,在OJ上面做题的时候,如果有很大的数据输入,就不要用cin,用scanf,或者按章上面那篇文章中的取消cin与stdin的同步然后再用cin。另外,这是一道模板类型的题目。
- 关键路径——杭电 4109
- 图——关键路径
- 【关键路径】hdu 4109
- 软件设计师重点难点——关键路径
- 软件设计师重点难点——关键路径
- HDU4109——Instrction Arrangement(关键路径)
- PMP知识点总结—关键路径法
- PMP知识点总结—关键路径法
- 杭电1874————单源最短路径(dijkstra)
- 杭电1385————Dijkstra+输出路径
- 数据结构 — 图 之 关键路径、关键活动 (文字表述)
- AOE网络与关键路径(二)——实现
- 图——关键路径用JAVA代码实现
- SDUT——2498AOE网上的关键路径
- 关键路径转化率分析——漏斗模型
- 学习笔记:浏览器渲染优化——关键渲染路径
- 关键路径(AOE)—基于拓扑排序(AOV)
- 关键路径
- Linux Makefile中 = := ?=
- maven安装和环境变量配置
- POJ 2479 Maximum sum (2593)
- Zeros and Ones
- 右键添加cmd的技巧
- 关键路径——杭电 4109
- C++ 后缀转换中缀表达式
- 机器学习经典论文
- 修改Ubuntu和WIN7双系统的默认启动系统
- java递归算法
- list与ArrayList的区别
- win7下Ubuntu的安装
- FFmpeg队列之add_to_pktbuf入队函数浅显分析
- 数组实现学生成绩录入、求最高分、最低分、平均分和排序