zoukankan      html  css  js  c++  java
  • 【JZOJ3400】旅行

    description

    从前有一位旅者,他想要游遍天下所有的景点。这一天他来到了一个神奇的王国:在这片土地上,有n个城市,从1到n进行编号。王国中有m条道路,第i条道路连接着两个城市ai,bi,由于年代久远,所有的道路都已经不能使用。如果要修复第i条道路,需要wi的时间。为了更好的旅行,旅者想要将某些道路修复,使得1号城市能够到达n号城市,2号城市能够到达n-1号城市..k号城市能够到达n-k+1号城市。为了满足他的要求,请问最少需要多少时间去修复道路。无解请输出-1。


    analysis

    • 可以(O(4!))暴力枚举这(k)组关系的顺序

    • 然后依次跑(SPFA),每跑一次把最短路上的边权标零,记录最小值即可

    • 听着是不是没有问题?其实这是水法,连拍都过不了233

    • 正解斯坦纳树,我还不会


    code

    #pragma GCC optimize("O3")
    #pragma G++ optimize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #define MAXN 10005
    #define MAXM 20005
    #define INF 1000000007
    #define ll long long
    #define reg register ll
    #define fo(i,a,b) for (reg i=a;i<=b;++i)
    #define fd(i,a,b) for (reg i=a;i>=b;--i)
    #define rep(i,a) for (reg i=last[a];i;i=next[i])
    
    using namespace std;
    
    ll last[MAXM],next[MAXM],tov[MAXM],len[MAXM];
    ll f[5],pre[MAXN][2],dis[MAXN];
    bool bo[5],bz[MAXN];
    ll n,m,k,tot,ans=INF;
    deque<ll>q;
    
    struct edge
    {
    	ll x,y,z;	
    }a[MAXN];
    
    inline ll read()
    {
    	ll x=0,f=1;char ch=getchar();
    	while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
    	while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    inline ll min(ll x,ll y){return x<y?x:y;}
    inline void link(ll x,ll y,ll z)
    {
    	next[++tot]=last[x],last[x]=tot,tov[tot]=y,len[tot]=z;	
    }
    inline ll spfa(ll S,ll T)
    {
    	memset(bz,1,sizeof(bz));
    	memset(pre,0,sizeof(pre));
    	memset(dis,64,sizeof(dis));
    	q.push_back(S),bz[S]=dis[S]=0;
    	while (!q.empty())
    	{
    		ll now=q.front();q.pop_front(),bz[now]=1;
    		rep(i,now)if (dis[now]+len[i]<=dis[tov[i]])
    		{
    			dis[tov[i]]=dis[now]+len[i],pre[tov[i]][0]=now,pre[tov[i]][1]=i;
    			if (bz[tov[i]])
    			{
    				bz[tov[i]]=0;
    				if (!q.empty() && dis[tov[i]]<dis[q.front()])q.push_front(tov[i]);
    					else q.push_back(tov[i]);
    			}
    		}
    	}
    	return dis[T];
    }
    inline void dfs(ll x)
    {
    	if (x>k)
    	{
    		ll cnt=0;
    		memset(last,0,sizeof(last)),memset(next,0,sizeof(next)),
    		memset(tov,0,sizeof(tov)),memset(len,0,sizeof(len)),tot=1;
    		fo(i,1,m)link(a[i].x,a[i].y,a[i].z),link(a[i].y,a[i].x,a[i].z);
    		fo(i,1,k)
    		{
    			ll beg=f[i],end=n-f[i]+1,pos=end;
    			ll tmp=spfa(beg,end);
    			if (tmp>=INF)return;cnt+=tmp;
    			while (pos!=beg)len[pre[pos][1]]=len[pre[pos][1]^1]=0,pos=pre[pos][0];
    		}
    		ans=min(ans,cnt);
    		return;
    	}
    	fo(i,1,k)if (bo[i])bo[i]=0,f[x]=i,dfs(x+1),bo[i]=1;
    }
    int main()
    {
    	n=read(),m=read(),k=read();
    	fo(i,1,m)a[i].x=read(),a[i].y=read(),a[i].z=read();
    	memset(bo,1,sizeof(bo)),dfs(1);
    	if (ans<INF)printf("%lld
    ",ans);
    	else printf("-1
    ");
    	return 0;
    }
    
  • 相关阅读:
    better-scroll 外层可以用positon:fixed 内层只能用position:absolute,不能用positon:fixed
    react中let一些数据是在render里,不是在retrun里
    onClick和ontouchmove一个是pc端一个是移动端,但是还是不知道有什么具体差别
    react中reder->return里: 1.有引号输入内容为'123' 2.没有引号输入内容为<p>123</p>
    if( 1<a<5 )这种写法是错误的,计算机不认识。正确写法是( a>1 && a<5),要不然会有运算法呢
    e.target
    transform: translateY(-50%) 实现元素垂直居中效果
    Uncaught TypeError: Cannot read property 'trim' of undefined
    push()方法返回的是数组新的长度
    transparent是透明的意思,实际上background默认的颜色就是透明的属性
  • 原文地址:https://www.cnblogs.com/horizonwd/p/11180176.html
Copyright © 2011-2022 走看看