2014在百度之星资格赛的第二个问题Disk Schedule

事实上,我认为它可以用来费用流问题。但光建地图上加班。

。。不科学啊。。

因副作用太大,否则,必然在。最后,想啊想,或者使用dp对。。。。

别想了一维dp。。。

。我不知道我是怎么想。无论如何,这是ac该

//#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<cassert>
#include<cstring>
#include<iomanip>
using namespace std;
#ifdef _WIN32
#define i64 __int64
#define out64 "%I64d
"
#define in64 "%I64d"
#else
#define i64 long long
#define out64 "%lld
"
#define in64 "%lld"
#endif
/************ for topcoder by zz1215 *******************/
#define foreach(c,itr)  for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)
#define FF(i,a)         for( int i = 0 ; i < (a) ; i ++)
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)
#define S64(a)          scanf(in64,&a)
#define SS(a)           scanf("%d",&a)
#define LL(a)           ((a)<<1)
#define RR(a)           (((a)<<1)+1)
#define pb              push_back
#define pf              push_front
#define X               first
#define Y               second
#define CL(Q)           while(!Q.empty())Q.pop()
#define MM(name,what)   memset(name,what,sizeof(name))
#define MC(a,b)		memcpy(a,b,sizeof(b))
#define MAX(a,b)        ((a)>(b)?

(a):(b)) #define MIN(a,b) ((a)<(b)?

(a):(b)) #define read freopen("in.txt","r",stdin) #define write freope("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 1111; int dp[maxn]; int t[maxn]; int s[maxn]; int m,n; int pas[maxn]; int pass(int a,int b) { if(a>=b) return 0; return pas[b]-pas[a]; } int find(int x,int y) { return min(abs(x-y),360-abs(x-y)); } int dis(int a,int b) { return abs(t[b]-t[a])*400 + find(s[b],s[a]); } int main() { cin>>m; for(int tt=1;tt<=m;tt++) { cin>>n; t[0] = 0; s[0] = 0; for(int i=1;i<=n;i++) { SS(t[i]); SS(s[i]); } pas[0] = 0; for(int i=1;i<=n;i++) { pas[i] = pas[i-1]+dis(i-1,i); } dp[0] = 0; for(int i=1;i<=n;i++) { dp[i] = dis(0,i) + pass(0,i-1); for(int j=1;j<i;j++) { dp[i] = min(dp[i], dp[j] + dis(j,i) + dis(j-1,j+1)+pass(j+1,i-1) ); dp[i] = min(dp[i], dp[j] + dis(j,i)+ pass(j-1,i-1)); dp[i] = min(dp[i], dp[j] + dis(j-1,i) + pass(j,i-1)); } } dp[n]+=dis(n-1,n)+n*10; cout<<dp[n]<<endl; } return 0; }



接下来是费用流tle代码。大概意思就是把数据点的那条边的费用变成一个非常小的负数。那么,一定要会选择那条边,不然得到的一定不是最小费用流,这样就起了限制作用


//#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<cassert>
#include<cstring>
#include<iomanip>
using namespace std;
#ifdef _WIN32
#define i64 __int64
#define out64 "%I64d
"
#define in64 "%I64d"
#else
#define i64 long long
#define out64 "%lld
"
#define in64 "%lld"
#endif
/************ for topcoder by zz1215 *******************/
#define foreach(c,itr)  for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)
#define FF(i,a)         for( int i = 0 ; i < (a) ; i ++)
#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)
#define S64(a)          scanf(in64,&a)
#define SS(a)           scanf("%d",&a)
#define LL(a)           ((a)<<1)
#define RR(a)           (((a)<<1)+1)
#define pb              push_back
#define pf              push_front
#define X               first
#define Y               second
#define CL(Q)           while(!Q.empty())Q.pop()
#define MM(name,what)   memset(name,what,sizeof(name))
#define MC(a,b)        memcpy(a,b,sizeof(b))
#define MAX(a,b)        ((a)>(b)?(a):(b))
#define MIN(a,b)        ((a)<(b)?(a):(b))
#define read            freopen("in.txt","r",stdin)
#define write           freope("out.txt","w",stdout)

const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;
const double oo = 10e9;
const double eps = 10e-9;
const double pi = acos(-1.0);
const int maxn = 2222;
const int add = 1111;

int m,n;
int t[add];
int s[add];

struct zz
{
    int from;
    int to;
    i64 c;
    i64 cost;
    int id;
}zx;

int start = 0;
int end = 2221;
i64 cc = 100000000;

vector<zz>g[maxn];
i64 way[maxn];
int bid[maxn];
bool inq[maxn];

void link(int now,int to,int c,i64 cost,int bc=0)
{
    zx.from = now;zx.to=to;zx.c=c;zx.cost=cost;
    zx.id = g[zx.to].size();
    g[zx.from].pb(zx);
    swap(zx.from,zx.to);
    zx.c=bc;zx.cost=-cost;
    zx.id = g[zx.to].size()-1;
    g[zx.from].pb(zx);
    return ;
}

bool spfa()
{
    for(int i=0;i<maxn;i++)
    {
        way[i]=inf64;   // 最小费用流
    }
    way[start]=0;
    deque<int>q;
    MM(inq,false);
    inq[start]=true;
    q.pb(start);
    i64 now,to,temp;
    while(!q.empty())
    {
        now = q.front();
        q.pop_front();
        for(int i=0;i<g[now].size();i++)
        {
            to = g[now][i].to;
            if(g[now][i].c>0)
            {
                temp = g[now][i].cost+way[now];
                if(temp<way[to])
                {
                    bid[to] = g[now][i].id;
                    way[to] = temp;
                    if(!inq[to])
                   {
                        inq[to]=true;
                        if(q.empty() || way[to]<way[q.front()]) q.pf(to);   // 最小费用流
                        else
                        q.pb(to);
                    }
                }
            }
        }
        inq[now]=false;
    }
    return way[end]!=inf64;
}
pair<i64,i64> dfs(i64 flow = inf64,i64 to = end)
{
    if(to == start) return make_pair(flow,0);
    i64 now=g[to][bid[to]].to;
    int id = g[to][bid[to]].id;
    pair<i64,i64>temp=dfs(min(flow,g[now][id].c),now);
    g[now][id].c-=temp.X;
    g[to][bid[to]].c+=temp.X;
    temp.Y+=temp.X*g[now][id].cost;
    return temp;
}

i64 gao()
{
    i64 ans=0;
    spfa();
    ans+=dfs().Y;
    spfa();
    ans+=dfs().Y;
    return ans;
}

int find(int x,int y)
{
    return min( abs(x-y), 360 - abs(x-y));
}

int dis(int at,int as,int bt,int bs)
{
    return (abs(bt-at))*400 + find(as,bs);
}

void build()
{
    for(int i=0;i<maxn;i++)
    {
        g[i].clear();
    }
    for(int i=1;i<=n;i++)
    {
        link(start,i,1,dis(0,0,t[i],s[i]));
    }
    link(start,end,1,dis(0,0,t[n],s[n]));
    for(int i=1;i<=n;i++)
    {
        link(i,i+add,1,-cc);
        for(int j=i+1;j<=n;j++)
        {
            link(i+add,j,1,dis(t[i],s[i],t[j],s[j]));
        }
    }
    for(int i=1;i<=n;i++)
    {
        link(i+add,end,1,dis(t[i],s[i],t[n],s[n]));
    }
    return ;
}

int main()
{
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>t[i]>>s[i];
        }
        build();
        i64 ans = gao();
        ans += cc*n;
        ans += 10*n;
        cout<<ans<<endl;
    }    
    return 0;
}



版权声明:本文博主原创文章。博客,未经同意不得转载。

原文地址:https://www.cnblogs.com/zfyouxi/p/4874175.html