• 「HNOI2015」菜肴制作


    「HNOI2015」菜肴制作

    这道题想到了其实还挺水的,一开始我直接用小根堆拓扑然后就爆0了,然后我又用十万个堆搜索,T30,还是xkl告诉我要倒着拓扑。

    首先要建反图,对于入度为0的点,较小的点先输出所以要优先拓扑大的点,这样就保证了大的点及其子树(其实并不是树,这样好理解点)都存在数组前面,再倒着输出即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<time.h>
    #include<queue>
    #define ma(x) memset(x,0,sizeof(x))
    using namespace std;
    struct edge
    {
    	int u,v,nxt;
    	#define u(x) ed[x].u
    	#define v(x) ed[x].v
    	#define n(x) ed[x].nxt
    }ed[100010];
    int first[100010],num_e=1;
    #define f(x) first[x]
    int d;
    int n,m,du[100010],ans[100010],cnt;
    bool v[100010];
    inline void add(int u,int v)
    {
    	++num_e;
    	u(num_e)=u;
    	v(num_e)=v;
    	n(num_e)=f(u);
    	f(u)=num_e;
    }
    bool ved[100010],ving[100010];
    signed main()
    {
    //	freopen("in.txt","r",stdin);
    //	freopen("4.in","r",stdin);
    //	freopen("1.out","w",stdout);
    
    	cin>>d;
    	while(d--)
    	{	
    		ma(ed);ma(first);ma(du);ma(ans);ma(v);
    		cnt=0;num_e=1;
    		scanf("%d%d",&n,&m);
    		int a,b;
    		for(int i=1;i<=m;i++)
    		{
    			scanf("%d%d",&a,&b);
    			add(b,a);
    			du[a]++;
    		}
    		priority_queue<int> q;
    		for(int i=1;i<=n;i++)
    		if(!du[i]){v[i]=1;q.push(i);}		
    		if(q.empty()){puts("Impossible!");continue;}
    		while(q.size())
    		{
    			int k=q.top();q.pop();
    			ans[++cnt]=k;
    			for(int i=f(k);i;i=n(i))
    			if(!v[v(i)])
    			{
    				du[v(i)]--;
    				if(!du[v(i)])
    				{
    					v[v(i)]=1;
    					q.push(v(i));
    				}
    			}
    			
    		}
    		if(cnt!=n){puts("Impossible!");continue;}
    		for(int i=cnt;i;i--)
    			printf("%d ",ans[i]);puts("");
    	}
    }
    
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<queue>
      5 #define ma(x) memset(x,0,sizeof(x))
      6 using namespace std;
      7 struct edge
      8 {
      9     int u,v,nxt;
     10     #define u(x) ed[x].u
     11     #define v(x) ed[x].v
     12     #define n(x) ed[x].nxt
     13 }ed[100010];
     14 int first[100010],num_e=1;
     15 #define f(x) first[x]
     16 int d;
     17 int n,m,du[100010],ans[100010],cnt;
     18 bool v[100010];
     19 int minn[100010];
     20 bool pd=0;
     21 inline void add(int u,int v)
     22 {
     23     ++num_e;
     24     u(num_e)=u;
     25     v(num_e)=v;
     26     n(num_e)=f(u);
     27     f(u)=num_e;
     28 }
     29 priority_queue<int,vector<int>,greater<int> >q[100010],temm;
     30 void dfs1(int x,int fa)
     31 {
     32     v[x]=1;q[x].push(x);
     33     for(int i=f(x);i;i=n(i))
     34     if(v(i)!=fa)
     35     {
     36         if(!v[v(i)])dfs1(v(i),x);
     37         temm=q[v(i)];
     38         while(temm.size())
     39         {
     40             q[x].push(temm.top());
     41             temm.pop();
     42         }
     43     }
     44 }
     45 bool ved[100010],ving[100010];
     46 void dfs2(int x)
     47 {
     48 //    cout<<x<<endl;
     49     if(pd)return;
     50     ving[x]=1;
     51 //    cout<<q[x].size()<<endl;
     52 //    while(!q[x].empty()&&q[x].top()==x)q[x].pop();
     53 //    cout<<q[x].size()<<endl;
     54     while(q[x].size())
     55     {
     56         while(!q[x].empty()&&q[x].top()==x)q[x].pop();
     57         if(q[x].empty())break;
     58         int k=q[x].top();q[x].pop();
     59 //        cout<<k<<endl;
     60         if(ving[k]){pd=1;return;}
     61         if(!ved[k])dfs2(k);
     62     }
     63     ving[x]=0;ved[x]=1;
     64     ans[++cnt]=x;
     65 }
     66 signed main()
     67 {
     68 //    freopen("in.txt","r",stdin);
     69 //    freopen("1.in","r",stdin);
     70 //    freopen("1.out","w",stdout);
     71 
     72     cin>>d;
     73     while(d--)
     74     {    
     75         ma(ed);ma(first);ma(du);ma(ans);ma(v);ma(minn);ma(q);ma(ving);ma(ved);
     76         pd=cnt=0;num_e=1;
     77         scanf("%d%d",&n,&m);
     78         int a,b;
     79         for(int i=1;i<=m;i++)
     80         {
     81             scanf("%d%d",&a,&b);
     82             add(b,a);
     83             du[b]++;
     84         }
     85         for(int i=1;i<=n;i++)
     86         if(!v[i])dfs1(i,0);
     87         for(int i=1;i<=n;i++)
     88         if(!ved[i])dfs2(i);
     89 /*        for(int i=1;i<=n;i++)
     90         {
     91             printf("#%d:
    ",i);
     92             while(q[i].size())
     93             {
     94                 cout<<q[i].top()<<endl;
     95                 q[i].pop();
     96             }
     97         }*/
     98         
     99         if(pd){puts("Impossible!");continue;}
    100         for(int i=1;i<=cnt;i++)
    101             printf("%d ",ans[i]);puts("");
    102     }
    103 }
    附十万个堆代码
    波澜前,面不惊。
  • 相关阅读:
    四则运算
    读书计划
    典型用户和场景分析
    课堂练习--电梯调度
    重力解锁--用户需求调研
    书籍促销活动优惠问题
    小组开发项目--NABC分析
    梦断代码读后感之终结篇
    结对开发-求环状二维数组最大子数组
    结对开发之大数溢出
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11173828.html
Copyright © 2020-2023  润新知