HDU 1285 确定比赛名次(拓扑排序模板)
2014-08-06 08:25
218 查看
题意还是比较容易理解的,关键要看到后面的:合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;
思路:这道题就是拓扑排序的经典应用了,用队列做的考虑优先编号小的出队就可以了。
拓扑排序:
拓扑排序是对有向无回路图(DAG)顶点的一种排序,它使得如果存在从u到v的有向路径,那么满足序列中u在v前。
所以我们的算法可以描述为这样一个过程:
1、找到整个图中所有的度为0的点,将这些点压进队列(栈)中
2、从队列(栈)中取出一点,输出,将该点及它的边删除,找到它所指向的点,如果改点是一个原点(删除指向它的点后),则压入队列(栈)
3、重复2过程,直到它为空
注:所谓度为0,即没有子节点,为1则只有一个,为2则有2个。为什么要先让度为0的点出来?因为你在定义的时候,度为0的点,则说明其没有父节点,即没有人排在它的前面!
所以基本AC代码:
优先队列优化后的代码:
思路:这道题就是拓扑排序的经典应用了,用队列做的考虑优先编号小的出队就可以了。
拓扑排序:
拓扑排序是对有向无回路图(DAG)顶点的一种排序,它使得如果存在从u到v的有向路径,那么满足序列中u在v前。
所以我们的算法可以描述为这样一个过程:
1、找到整个图中所有的度为0的点,将这些点压进队列(栈)中
2、从队列(栈)中取出一点,输出,将该点及它的边删除,找到它所指向的点,如果改点是一个原点(删除指向它的点后),则压入队列(栈)
3、重复2过程,直到它为空
注:所谓度为0,即没有子节点,为1则只有一个,为2则有2个。为什么要先让度为0的点出来?因为你在定义的时候,度为0的点,则说明其没有父节点,即没有人排在它的前面!
所以基本AC代码:
#include<iostream> #include<cstring> using namespace std; int map[502][502],flag[502],m,n,val[502]; void topsort() { int i, j, k=1; for(i=1; i<=n; i++) //有n个点,所以要找n次 { for(j=1; j<=n; j++) { if(flag[j]==0) //循环寻找度为0的点 { flag[j]--; val[k++]=j; for(int x=1; x<=n; x++) //删除指向该点的边 if(map[j][x]) flag[x]--; //使其度为0 break; } if(j>n) return ; } } } int main() { int i,j; while(cin>>n>>m) { memset(map,0,sizeof(map)); memset(flag,0,sizeof(flag)); //初始化所有的点的度为0 int a,b; for(i=1;i<=m;i++) { cin>>a>>b; if(!map[a][b]) { map[a][b]=1; flag[b]++; //度增加 } } topsort(); for(i=1;i<=n; i++) if(i!=n) cout<<val[i]<<" "; else cout<<val[i]<<endl; } return 0; }
优先队列优化后的代码:
#include<cstdio> #include<cstring> #include<queue> #include<vector> #include<algorithm> using namespace std; const int N=510+10; vector<int> g ; //邻接表 int du ,val ; int n,m; void topsort() { int i; priority_queue<int, vector<int>, greater<int> > q;//定义一个优先队列,并定义编号小的优先出队 for(i=1;i<=n;i++) if(!du[i]) q.push(i); int cnt=1; while(!q.empty()) { int u=q.top(); q.pop(); val[cnt++]=u; for(i=0;i<g[u].size();i++) { int v=g[u][i]; du[v]--; if(!du[v]) q.push(v); } } } int main() { int i,j,u,v; while(scanf("%d %d",&n,&m)!=EOF) { memset(du,0,sizeof(du)); for(i=1;i<=n;i++)g[i].clear(); for(i=1;i<=m;i++) { scanf("%d %d",&u,&v); g[u].push_back(v); du[v]++; } topsort(); for(i=1;i<=n;i++) { if(i!=n) printf("%d ",val[i]); else printf("%d\n",val[i]); } } return 0; }
相关文章推荐
- 确定比赛名次 1285(拓扑排序 模板)
- hdu 1285 确定比赛名次 (浙大拓扑排序模板)
- 确定比赛名次(拓扑排序模板(比之前的模板纠正和完善了,之前的会有bug,一些题有时会wa))
- HDU-1285-确定比赛名次-拓扑排序(模板)
- HDU 1285 确定比赛名次(拓扑排序)
- hdu 1285 (确定比赛名次)(拓扑排序)
- HDU 1285 确定比赛名次 拓扑排序模板题
- HDU 1285 -- 确定比赛名次 (拓扑排序)
- hdu 1285 确定比赛名次(拓扑排序)
- HDOJ题目1285确定比赛名次(拓扑排序,模板)
- HDU-1285-确定比赛名次【拓扑排序模板】
- HDU 1285 确定比赛名次 拓扑排序水题
- hdu 1285 确定比赛名次 拓扑排序模板题 优先队列
- 拓扑排序模板-优先队列 hdu 1285 确定比赛名次
- HDU1285 确定比赛名次(拓扑排序模板)
- hduoj1285确定比赛名次(拓扑排序模板)
- HD-1285-确定比赛名次(拓扑排序模板题)
- hdu 1285 确定比赛名次 简单的拓扑排序模板题~~需要注意重边
- hdoj 1285 确定比赛名次 ( 拓扑排序--三种模板 )
- hdu 1285 确定比赛名次(拓扑排序)