省赛后周赛1

A题

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=117863#problem/B

题意:

裸拓扑排序,先出现的必须在后面那个前面
拓扑排序:找到入度为0的点,加入队列,把入度为零的点的链接点入度减1,遇到入度为0的加入队列、

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 110;
int n, m;
int indegree[maxn] , mapa[maxn][maxn], res[maxn];
queue <int> q;

void tp()
{
    int cnt = 0;
    for (int i = 1; i <= n; i++)
        if (indegree[i] == 0)
            q.push(i);
    while (!q.empty())
    {
        //cout << res[4]<<endl;
        int temp = q.front();
        q.pop();
        res[cnt++] = temp;
        for (int i = 1; i <= n; i++)
            if (mapa[temp][i] && --indegree[i] == 0)
                    {
                     // indegree[i] --;
                        q.push(i);
                    }
    }
    for (int i = 0; i < cnt; i++)
        printf("%d%c", res[i],(i == cnt-1) ? '\n' :' ');
}


int main()
{
    while (scanf("%d%d", &n, &m) )
    {
        if(n == 0 && m == 0)
            break;
        memset(mapa, 0, sizeof(mapa));
        memset(indegree, 0, sizeof(indegree));
        int a, b;
        for (int i = 0; i < m; i++)
        {
            scanf("%d%d", &a, &b);
            mapa[a][b] = 1;
            indegree[b]++;
        }
        tp();
    }
    return 0;
}

B题

题意:

有n个精灵在一维坐标轴上,并且每个精灵都有一个权值,每个精灵从一个点到达一个点要花费:S3*W(s代表距离),问所有的精灵要聚在一起,最小花费是多少。
设最终要求的点的位置是x,则花费为:∑fabs(x[i]-x)^3*w[i]。此函数为凸函数,因此可以三分。

题解:

三分:

lchild 为mid值,rchild为mid和最右值得中间值,然后用函数值判断是否符合条件,根据所求为极大值还是极小值不同最终是将左值给mid还是右值需要考虑。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>

int n;
double x[50010],w[50010];
using namespace std;

double cul(double mid)
{
    double ans=0;
    for(int i=0;i<n;i++)
    {
        double dis=fabs(mid-x[i]);
        ans+=dis*dis*dis*w[i];
    }
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);

   for (int ca = 1 ;ca <= T ;ca++)
    {
        scanf("%d",&n);
        for (int i = 0 ; i < n ;i++)
            scanf("%lf%lf",&x[i],&w[i]);
        double l = x[0],r = x[n-1],lmid,rmid;

          while(r-l>1e-9)
        {
            lmid=(l+r)/2;
            rmid=(lmid+r)/2;
            if(cul(lmid) < cul(rmid))
                r = rmid;
            else
                l=lmid;
        }

        double ans1=cul(l);
        double ans2=cul(r);

        printf("Case #%d: %.lf\n",ca,min(ans1,ans2));
    }
}

你可能感兴趣的:(省赛后周赛1)