2017、5、13日省赛前组队训练赛。

long long是种玄学

hdu4968 贪心 (wa了一发,代码bug问题)

hdu4970 离线加区间的值O(n),用的优先队列,读取到头就+攻击,到尾就减攻击。

正解是O(n)的处理,即把l, r,  d, 用数组a[l] += d;  a[r+1] = -d; 然后从前向后扫一遍就 能计算出每一个格子的伤害

一样的思想,不一样的做法!!

树状数组也可以。

hdu 4967 用sqrt的方法求因子。

hdu 4966(note)(wa了n发,long long 是玄学 注意int *int 也是会爆int )

学会用朱_流算法找最小树形图。

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

using namespace std;
const int maxn=51*2100;
const int N=100001,M=1000001,inf=2147483647;
struct edge {int u,v,w;} e[M];
int n,m,ans,id[maxn],pre[maxn],inw[maxn];
int mk[55],a[55];
int in[maxn],vis[maxn];

int zhuliu(int r,int V,int E)//树根 结点数 边数  
{  
    int cnt;  
    memset(pre,-1,sizeof pre);  
    ans=0;//最小树形图的权值  
    while(1)  
    {  
        int u,v,i;  
        //找最小入边  
        for(i=0;i<=V;i++)  
            in[i]=inf;//记该点入边最小的权值  
        for(i=1;i<=E;i++)  
        {  
            u=e[i].u;  
            v=e[i].v;  
            if(e[i].w<in[v] && u!=v)  
            {  
                pre[v]=u;//记录权值最小入边的那个入点  
                in[v]=e[i].w;  
            }  
        }
        for(i=0;i<=V;i++)//判断图不连通 直接返回  
            if(i!=r&&in[i]==inf) return -1;  
        //找环  
        cnt=0;//记缩点后的联通块编号  
        memset(id,-1,sizeof id);//id[i]表示i缩点后在哪个联通块  
        memset(vis,-1,sizeof vis);  
        in[r]=0;  
        for(i=0;i<=V;i++)  
        {  
            ans+=in[i];  
            v=i;  
            while(vis[v]!=i&&v!=r&&id[v]==-1)//找环  
            {  
                vis[v]=i;  
                v=pre[v];  
            }  
            if(v!=r&&id[v]==-1)//缩点  
            {  
                for(u=pre[v];u!=v;u=pre[u])  
                    id[u]=cnt;  
                id[v]=cnt++;  
            }  
        }  
        if(cnt==0) break;//无环则结束  
        //建新图  
        for(i=0;i<=V;i++)  
            if(id[i]==-1) id[i]=cnt++;  
        for(i=1;i<=E;i++)  
        {  
            u=e[i].u;  
            v=e[i].v;  
            e[i].u=id[u];  
            e[i].v=id[v];  
            if(id[u]!=id[v]) e[i].w-=in[v];  
        }  
        V=cnt-1;  
        r=id[r];  
    }
    return 1;  
}
int main()
  {
      //freopen("in.txt","r",stdin);
    int i,j,k,f1,f2,f3,f5,f4,t1,t2,t3,t4;
    int n2;
    while(scanf("%d%d",&n,&n2)==2&&(n||n2)){
    t2=0;
    m=0;
    mk[0]=0;a[0]=0;
    for(i=1;i<=n;i++){
        scanf("%d",&a[i]);
        mk[i]=mk[i-1]+a[i-1]+1; //由之前决定其的开头处
        m+=a[i]+1;
    }
    for(i=1;i<=n;i++){
        e[++t2].u=0; //0到任意课程的0级都是0的权值 
        e[t2].v=mk[i];
        e[t2].w=0;
        for(j=1;j<=a[i];j++){
            e[++t2].u=mk[i]+j;
            e[t2].v=mk[i]+j-1;
            e[t2].w=0;        
            }
    }
    for(i=1;i<=n2;i++){
        scanf("%d %d %d %d %d",&f1,&f2,&f3,&f4,&f5);
        e[++t2].u=mk[f1]+f2;
        e[t2].v=mk[f3]+f4;
        e[t2].w=f5;
    }
    if(zhuliu(0,m,t2)!=-1) //以0作为根结点,m为点的数量,t2为边的数量 
    cout << ans << endl;
    else
    cout << "-1" << endl;
}
    return 0;
  }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值