ACM-ICPC实验室20.2.21测试-图论
Posted zhanglichen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM-ICPC实验室20.2.21测试-图论相关的知识,希望对你有一定的参考价值。
A.患者的编号
给出一个有向图,要求你输出字典序最小的拓扑排序。
常规拓扑排序是做不了的,正解是反向建图,同时用大根堆的优先队列维护,保证每次优先访问编号大的结点,再反向输出~
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+14; vector<int> g[maxn]; vector<int> topOrder; int inDegree[maxn]; int N,M,x,y; void topSort () { priority_queue<int> q; for (int i=1;i<=N;i++) if (inDegree[i]==0) q.push(i); while (!q.empty()) { int u=q.top(); q.pop(); topOrder.push_back(u); for (int i=0;i<g[u].size();i++) { int v=g[u][i]; if (--inDegree[v]==0) q.push(v); } } } int num[maxn]; int main () { while(~scanf("%d %d",&N,&M)) { fill(inDegree,inDegree+maxn,0); topOrder.clear(); for (int i=0;i<maxn;i++) g[i].clear(); for (int i=0;i<M;i++) { scanf("%d %d",&x,&y); g[y].push_back(x); inDegree[x]++; } topSort(); for (int i=0;i<topOrder.size();i++) { num[topOrder[i]]=N-i; } for (int i=1;i<=N;i++) { if (i!=1) printf (" "); printf ("%d",num[i]); } printf (" "); } return 0; }
D.传送门
特殊的,点的权值也可以作为最小生成树的边,建树时贪心操作即可~
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2014; const ll inf=1e18; ll g[maxn][maxn]; ll w[maxn]; int visit[maxn]; ll d[maxn]; ll c[maxn]; int N; ll prim (int s) { fill (d,d+maxn,inf); fill (visit,visit+maxn,0); d[s]=w[s]; ll ans=0; for (int i=1;i<=N;i++) { int u=-1;ll mmin=inf; for (int j=1;j<=N;j++) if (!visit[j]&&d[j]<mmin) { u=j; mmin=d[j]; } if (u==-1) return -1; visit[u]=1; ans+=d[u]; //printf ("%d ",d[u]); for (int v=1;v<=N;v++) if (!visit[v]&&v!=u) d[v]=min(w[v],min(d[v],g[u][v])); } return ans; } struct node { int x,y; }Node[maxn]; int main () { scanf("%d",&N); for (int i=1;i<=N;i++) for (int j=1;j<=N;j++) g[i][j]=inf; for (int i=1;i<=N;i++) scanf("%d %d",&Node[i].x,&Node[i].y); for (int i=1;i<=N;i++) scanf("%lld",&w[i]); for (int i=1;i<=N;i++) scanf("%lld",&c[i]); for (int i=1;i<=N;i++) { for (int j=i+1;j<=N;j++) { ll dis=(c[i]+c[j])*(abs(Node[i].x-Node[j].x)+abs(Node[i].y-Node[j].y)); //printf ("%lld ",dis); g[i][j]=g[j][i]=dis; } } int u=-1; ll mmin=inf; for (int i=1;i<=N;i++) { if (w[i]<mmin) { mmin=w[i];u=i; } } ll ans=prim(u); printf ("%lld ",ans); return 0; }
以上是关于ACM-ICPC实验室20.2.21测试-图论的主要内容,如果未能解决你的问题,请参考以下文章