暑期集训补题系列Day--3树/队列/栈

Day–3树/队列/栈

A.Useful Decomposition Codeforces 981C
题意:给你一棵N个结点的树,然后输入N-1条边。要求将该树拆成若干条简单路径,并且这些路径都经过一个公共节点。给出任意一个解决方案,如不存在输出No
思路:邻接表存图建双向边,如果一个点的出度>2,那么他就是那个共享的点,如果有两个共享的点,一定为NO。

我们把出度为1的点,存到一个数组中。如果有共享点,直接输出:共享点~这个数组中所有的点即可。

如果没有共享点,那么就是一条链的情况,输出两个出度为1的点即可。

#include 
using namespace std;
const int MAXN = 100005;
int n, xx;
vector<int> G[MAXN], s;
int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n-1; i++)
    {
        int u, v; scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    vector<int> x;
    int cnt = 0, s = 0;
    for (int i = 1; i <= n; i++)
    {
        if (G[i].size() == 1) x.push_back(i);
        if (G[i].size() > 2) s = i, cnt++;
    }
    if (cnt >= 2) printf("No\n");
    else
    {
        printf("Yes\n");
        if (s == 0)//没有分叉点即一条链的情况
        {
            printf("%d\n", 1);
            printf("%d %d\n", x[0], x[1]);
        }
        else
        {
            printf("%d\n", x.size());
            for (auto i: x) printf("%d %d\n", s, i);
        }
    }
    return 0;
}

C - Kefa and Park Codeforces 580C

#include 
#include 
#include 
#include 
using namespace std;

const int MAXN = 1e5 + 10;
int hasCat[MAXN], vis[MAXN];
int n, m, ans;
vector<int> G[MAXN];

int dfs(int cur, int ret) {
	if(hasCat[cur]) {ret++;}
	else {ret = 0;}
	if(ret > m || vis[cur]) {return 0;}
	vis[cur] = 1;
	int ans = 0;
	if(cur > 1 && G[cur].size() == 1) {return 1;}
	for(int i = 0; i < G[cur].size(); i++) {
		ans += dfs(G[cur][i], ret);
	}
	return ans;
}

int main() {
	//freopen("input.txt", "r", stdin);
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &hasCat[i]);
	}
	int u, v;
	for(int i = 1; i <= n - 1; i++) {
		scanf("%d %d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1, 0);
	printf("%d\n", dfs(1, 0));
	//fclose(stdin);
	return 0;
}

我写的dfsWA在了第8个样例,加上对n != 1的考虑后WA在了第9个样例。还没有到底为什么WA了,看下AC代码,发现在DFS时带上fa参数非常有用,可以避免第二次访问。(所以我为什么傻到没有弄个vis!!!)
E - Recursive Queries Codeforces 932B

#include
#define ll long long
using namespace std;
int ans[10][1000005],q,l,r,k;
int op(int x)         //f(n)函数的功能实现
{
    if(x<10)return x;
    int tmp,as;
    while(1)
    {
        as=1;
        while(x)
        {
            tmp=x%10;
            x/=10;
            if(tmp)as*=tmp;
        }
        if(as<10)return as;
        x=as;
    }
}
int main()
{
    for(int i=1;i<=9;i++)ans[i][0]=0;
    for(int i=1;i<=9;i++)              //前缀和打表
    {
        for(int j=1;j<=1000000;j++)
        {
            if(op(j)==i){ans[i][j]=ans[i][j-1]+1;}
            else ans[i][j]=ans[i][j-1];
        }
    }
    scanf("%d",&q);
    while(q--)         //在线查询
    {
        scanf("%d%d%d",&l,&r,&k);
        printf("%d\n",ans[k][r]-ans[k][l-1]);
    }
    return 0;
}

G - Okabe and Boxes Codeforces 821C

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

#define ll long long
#define REP(i,a) for(int i = 0; i < (a); i++)
#define PB push_back
#define SZ(a) (a).size()
#define MP make_pair
#define ALL(a) (a).begin(),(a).end()
#define fs first
typedef vector<int> vi;
typedef pair<int,int> pii;



int main()
{
    int n;
    cin >> n;
    stack<int> st;
    int curr=1;
    int ans = 0;
    REP(i,2*n){
        string str;
        cin >> str;
        assert(str[0]=='a' || str[0]=='r');
        if(str[0]=='a'){
            int x;
            cin >> x;
            st.push(x);
        }else if(str[0]=='r'){
            if(!st.empty()){
                if(st.top()==curr){ //last thing added is what we need to remove
                    st.pop();
                }else{ //last thing we added is NOT what we need to remove
                    ans++;
                    while(!st.empty()) st.pop(); //clears the stack
                }
            }
            curr++;
        }
    }
    cout << ans << endl;
}

I - Producing Snow Codeforces 948C

#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N=1e5+5;

LL t[N],sum[N],v[N];                             //sum[i]是t[i]的前缀和

int main(){
    priority_queue<LL,vector<LL>,greater<LL> >q;
    int n,m;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&v[i]);

    }
    for(int i=1;i<=n;i++){
        scanf("%lld",&t[i]);
        sum[i]=t[i]+sum[i-1];
    }
    for(int i=1;i<=n;i++){
        q.push(v[i]+sum[i-1]);                  //加上sum[i-1],可以在减的时候将前一段没有消融的sum[i-1]抵消掉
        LL ans=t[i]*q.size();                   //先假设没有一堆雪不够消融t[i]
        while(!q.empty()&&q.top()<=sum[i]){     //找到不够t[i]的,减掉差值(不够的部分)
            ans+=q.top()-sum[i];
            q.pop();
        }
        printf("%lld%c",ans,i==n?'\n':' ');
    }
    return 0;
}

你可能感兴趣的:(算法,树,队列,栈)