hdu5195 n个点m条边最多删k个边尽量使某种拓扑序最大:贪心+优先队列
比赛时总感觉很混乱,其实昨天晚上仔细一想就很简单了==
首先,我是知道我要拿最大id点且入度小于等于k的,那就拿,继而,需要将他相连边全部入度-1,如果入度小于等于k加入优先队列
一直到队列为空,类似bfs那样找,代码实现也比线段树好多了==
心塞,本来手速过A分挺高,手贱hack又是一夜回到解放前,又掉到紫名,何时能稳定啊啊啊
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 int now,my_head[200005],my_next[200005],my_point[200005]; 7 int into[200005],vis[200005],a[200005]; 8 priority_queue<int>q; 9 void add(int x,int y) 10 { 11 my_next[++now]=my_head[x]; 12 my_head[x]=now; 13 my_point[now]=y; 14 } 15 int main() 16 { 17 int n,m,k,i,j,cnt,x,y,u,v; 18 while (~scanf("%d%d%d",&n,&m,&k)) 19 { 20 memset(into,0,sizeof(into)); 21 memset(my_head,0,sizeof(my_head)); 22 now=0; 23 while (m--) 24 { 25 scanf("%d%d",&x,&y); 26 add(x,y); into[y]++; 27 } 28 cnt=0; 29 while (!q.empty()) q.pop(); 30 memset(vis,0,sizeof(vis)); 31 for (i=1;i<=n;i++) 32 if (into[i]<=k) q.push(i); 33 while (!q.empty()) 34 { 35 u=q.top(); q.pop(); 36 if (vis[u]||into[u]>k) continue; 37 vis[u]=1; 38 k-=into[u]; 39 a[++cnt]=u; 40 for (i=my_head[u];i;i=my_next[i]) 41 { 42 v=my_point[i]; 43 into[v]--; 44 if (into[v]<=k&&vis[v]==0) q.push(v); 45 } 46 } 47 for (i=1;i<cnt;i++) printf("%d ",a[i]); 48 printf("%d\n",a[cnt]); 49 } 50 return 0; 51 }