事实上,我认为它可以用来费用流问题。但光建地图上加班。
。。不科学啊。。
。
因副作用太大,否则,必然在。最后,想啊想,或者使用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; }
版权声明:本文博主原创文章。博客,未经同意不得转载。