[Bzoj4010] [HNOI2015] + topological sorting stack of dishes,
Title effect: seeking the minimum sequence number position (the location of each of the minimum numbers)
method 1:
The established chain, each needs to be placed in front of him to put in front of recursion to find the final table should be the answer, but he seems to be wrong
30·
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<iostream> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 const int maxn=1e5+5; 10 int n,m,T; 11 int fst[maxn],nxt[maxn],to[maxn],edge_count,indegree[maxn]; 12 inline void add(int x,int y){ 13 edge_count++; 14 to[edge_count]=y; 15 nxt[edge_count]=fst[x]; 16 fst[x]=edge_count; 17 indegree[y]++; 18 } 19 bool vis[maxn]; 20 queue<int>q; 21 int cnt; 22 inline bool topological_sort(){ 23 cnt=0; 24 for(int i=1;i<=n;i++)if(!indegree[i])q.push(i),cnt++; 25 while(q.size()){ 26 int u=q.front(); 27 q.pop(); 28 29 for(int i=fst[u];i;i=nxt[i]){ 30 int v=to[i]; 31 indegree[v]--; 32 if(!indegree[v])q.push(v),cnt++; 33 } 34 } 35 return cnt==n; 36 } 37 int pre[maxn],suf[maxn]; 38 inline void ins(int x,int P) { // inserted p (value) before X 39 int L = pre [P]; 40 pre [X] = L; 41 is SUF [L] = X; 42 is 43 is pre [P] = X; 44 is SUF [x] = P; 45 46 is VIS [x] = . 1 ; 47 } 48 inline void del ( int x) { // the x removed from the list 49 int L = pre [x]; 50 int R & lt = SUF [x ]; 51 is SUF [L] = R & lt; 52 is pre[r]=l; 53 } 54 inline void init(){ 55 for(int i=0;i<=n+1;i++){ 56 pre[i]=i-1; 57 suf[i]=i+1; 58 } 59 } 60 int flag[maxn]; 61 int temp[maxn],p; 62 inline void solve(int x,int y){//传数值 63 int dep=++cnt; 64 for(int k=x;pre[k]!=y;k=suf[k])flag[k]=dep; 65 66 for(int k=x;flag[k]==dep;k=suf[k]){ 67 p=0; 68 vis[k]=1; 69 70 for(int i=fst[k];i;i=nxt[i]){ 71 int v=to[i]; 72 if(!vis[v])temp[++p]=v; 73 } 74 if(p){ 75 sort(temp+1,temp+p+1); 76 for(int i=1;i<=p;i++){ 77 del(temp[i]); 78 ins(temp[i],k); 79 } 80 solve(temp[1],temp[p]); 81 } 82 } 83 if(x==1 && y==n){ 84 for(int k=1,ans=1;ans<=n;k=suf[k],ans++){ 85 printf("%d ",k); 86 } 87 printf("\n"); 88 } 89 } 90 inline void clear(){ 91 memset(indegree,0,sizeof(indegree)); 92 memset(fst,0,sizeof(fst)); 93 memset(nxt,0,sizeof(nxt)); 94 memset(to,0,sizeof(to)); 95 edge_count=0; 96 Memset (VIS, 0 , the sizeof (VIS)); // tag is processed 97 Memset (pre, 0 , the sizeof (pre)); 98 Memset (SUF, 0 , the sizeof (SUF)); 99 the init () ; 100 } 101 int main () { 102 103 Scanf ( " % D " , & T); 104 the while (T-- ) { 105 106 Scanf ( " % D% D " , & n-, & m); 107 clear(); 108 for(int i=1,a,b;i<=m;i++){ 109 scanf("%d%d",&a,&b); 110 add(b,a);//b前面有a 111 } 112 if(!topological_sort()){printf("impossible\n");continue;} 113 else cnt=0,solve(1,n); 114 } 115 return 0; 116 }
Hope dalao have come up with counter-examples ...
. . . Lv. . . rechardluan even within a few minutes to think of a counter-example
My algorithm is based on the guarantee nodes are smaller than x x in front, but the problem is that each treatment sequence does not necessarily meet the subject requirements (not exactly equivalent), such as a set of data is
5 3
5 2
4 2
3 5
12345 -> 1 45 23 -> 14 3 52
But the correct answer should be
13452
Correct answer:
Determining the location of a number, and when larger than this number, and he must be behind him back (he can not put a smaller place than before, there will be problems) only if
So we think contravened the map, find the largest zero each time a node deleted
Finally, reverse output is the answer, the perfect range to avoid recursion problems have said before
std:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<iostream> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 const int maxn=1e5+5; 10 int n,m,T; 11 int fst[maxn],nxt[maxn],to[maxn],edge_count,indegree[maxn]; 12 inline void add(int x,int y){ 13 edge_count++; 14 to[edge_count]=y; 15 nxt[edge_count]=fst[x]; 16 fst[x]=edge_count; 17 indegree[y]++; 18 } 19 bool vis[maxn]; 20 priority_queue<int>q; 21 int ans[maxn]; 22 int cnt; 23 inline bool topological_sort(){ 24 cnt=0; 25 for(int i=1;i<=n;i++)if(!indegree[i]){ 26 q.push(i); 27 } 28 while(q.size()){ 29 int u=q.top(); 30 ans[++cnt]=u; 31 q.pop(); 32 33 for(int i=fst[u];i;i=nxt[i]){ 34 int v=to[i]; 35 indegree[v]--; 36 if(!indegree[v])q.push(v); 37 } 38 } 39 return cnt==n; 40 } 41 inline void clear(){ 42 memset(indegree,0,sizeof(indegree)); 43 memset(fst,0,sizeof(fst)); 44 memset(nxt,0,sizeof(nxt)); 45 memset(to,0,sizeof(to)); 46 edge_count=0; 47 } 48 int main(){ 49 scanf("%d",&T); 50 while(T--){ 51 scanf("%d%d",&n,&m); 52 clear(); 53 for(int i=1,a,b;i<=m;i++){ 54 scanf("%d%d",&a,&b); 55 add(b,a);//b前面有a 56 } 57 if(!topological_sort()){printf("impossible\n");continue;} 58 else{ 59 for(int i=n;i;i--){ 60 printf("%d ",ans[i]); 61 } 62 printf("\n"); 63 } 64 } 65 return 0; 66 }
to sum up:
1. proof complexity of the algorithm. 2. proof of the correctness of the algorithm (greedy algorithms often need to think counter-example, to think from every step of the algorithm, to come up with may cause part of the problem)