[COGS2653]源符「厌川的翡翠」-网络流

来源:互联网 发布:域名云解析用吗 编辑:程序博客网 时间:2024/04/28 11:40

源符「厌川的翡翠」

题目更新:

现在第13,14,15,16组数据满足m=n-1
所有整数都是正整数
第7,8,9,10,11,12组数据的范围更改为:n,t<=40, m<=50
已添加一句话题意
已将样例2更换为更强的样例

请不要在代码或评论中添加任何可能引起时间以为单位变化的内容

【题目描述】

诹访子和神奈子需要合力帮助早苗!
早苗作为神社的风祝,有时也需要解决异变,但在一次异变中早苗遇到了非常强大的敌人,需要诹访子和神奈子的援助。诹访子打算使用符卡”源符「厌川的翡翠」”来帮助早苗,同时神奈子会使用藤蔓来增加诹访子符卡的威力。
符卡”源符「厌川的翡翠」”会放出n个翡翠,神奈子则会操纵m条藤蔓连接这些翡翠,一些翡翠可能会被藤蔓连接成一个环,但是没有两个翡翠连成的环中有相同的藤蔓,所有的翡翠都能通过藤蔓连接到其它翡翠。在战斗中诹访子可以任意将翡翠的硬度调节为[1,t]中的整数,如果第i个翡翠的硬度为j,则整个符卡会获得v[i][j]的不稳定系数,而且符卡的威力和用藤蔓连接的两个翡翠硬度的差值有关。
由于诹访子并不擅长数学,早苗又要与敌人交战,所以她请你来帮她找到一个最小的整数c,满足存在一种给翡翠设置硬度的方案,使得没有两个被藤蔓连接的翡翠硬度的差值大于c且所有翡翠的不稳定系数之和不大于w。

一句话题意:
给个仙人掌,仙人掌上每个点都能填入[1,t]中的整数,第i个点填j会获得收益v[i][j],求一个最小的c,使得存在一种填数的方案,满足没有两个用边相邻的点填的数差值超过c且所有点的收益和不超过w

【输入格式】

第一行四个整数n,m,w,t,意义如上
接下来m行,每行三个整数l和r,表示第l个铁轮和第r个翡翠用藤蔓连接在一起
接下来一个n行t列的整数矩阵,第i行第j列的数表示第i个翡翠硬度为j所获得的不稳定系数

【输出格式】

如果敌人太强了诹访子和神奈子联手都无法战胜,输出-1
否则一行一个整数c,意义如上

【样例输入1】

5 5 5 2
1 2
1 4
3 4
4 5
3 5
1 2
2 1
1 2
2 1
1 2

【样例输出1】

1

【样例输入2】

10 11 20 10
1 2
1 3
3 4
2 5
3 6
6 7
3 8
1 9
1 10
1 8
1 5
7 2 3 9 9 10 10 4 4 7
1 7 1 9 3 1 1 2 4 6
1 2 10 3 5 10 3 5 5 4
1 9 3 8 4 4 2 2 3 2
2 4 1 10 7 7 8 3 8 7
9 3 8 3 2 10 7 3 10 1
3 3 7 7 4 9 3 7 10 5
9 5 8 7 1 3 2 10 5 8
9 10 10 10 4 6 2 9 4 9
7 10 8 10 2 1 4 3 9 10

【样例输出2】

3

【数据范围】

n,t<=150,m<=200,w<=100000,v<=5000000

【ex】

还有诹访子和神奈子联合起来都打不过的人(妖怪/神……)?
正邪啊,谁自机谁最强seija1

吓得我都去玩 弹幕天邪鬼 了↓↓↓
seija2


《论根据名字选择题目的优越性2》
这题就是咱去做切糕的原因……


思路:
可以先去看看切糕
(这是一道题的名字不要误会)
看完想必就不需要往下看了,可以直接做出这道题了……

好吧其实还是有一点点区别的……
咱考虑二分这个答案c,使用网络流判断。
然后判定方法嘛……瞬间变成了切糕是不是呀……

#include<iostream>#include<vector>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>using namespace std;inline int read(){    int x=0;char ch=getchar();    while(ch<'0' || '9'<ch)ch=getchar();    while('0'<=ch && ch<='9')x=x*10+(ch^48),ch=getchar();    return x;}typedef pair<int,int> pr;const int NN=159;const int Inf=1e9;int n,m,w,d;vector<pr> wea;int v[NN][NN];const int N=1e5+9;const int M=1e6+9;inline int po(int u,int d){    return u+(d-1)*n;}int to[M],nxt[M],cap[M],beg[N],tot;int s,t,dis[N],q[N];inline void adde(int u,int v,int c){    to[++tot]=v;    nxt[tot]=beg[u];    cap[tot]=c;    beg[u]=tot;}inline void add(int u,int v,int c){    adde(u,v,c);    adde(v,u,0);}inline bool bfs(){    int l=0,r=1;    memset(dis,0,sizeof(dis));    q[1]=s;    dis[s]=1;    while(l<r)    {        int u=q[++l];        for(int i=beg[u],v;i;i=nxt[i])            if(!dis[v=to[i]] && cap[i])            {                dis[v]=dis[u]+1;                q[++r]=v;            }    }    return dis[t];}inline int dfs(int u,int mflow){    if(u==t || !mflow)        return mflow;    int cost=0;    for(int i=beg[u],v,f;i;i=nxt[i])        if(dis[v=to[i]]==dis[u]+1 && cap[i])        {            f=dfs(v,min(mflow-cost,cap[i]));            cap[i]-=f;            cap[i^1]+=f;            cost+=f;            if(mflow==cost)                break;        }    if(!cost)        dis[u]=-1;    return cost;}inline int dinic(){    int ret=0;    while(bfs())        ret+=dfs(s,Inf);    return ret;}inline void init(){    memset(nxt,0,sizeof(nxt));    memset(beg,0,sizeof(beg));    tot=1;}inline bool judge(int c){    init();    for(int j=1;j<=n;j++)    {        add(s,po(j,1),Inf);        add(po(j,d),t,v[j][d]);        for(int i=1;i<d;i++)            add(po(j,i),po(j,i+1),v[j][i]);    }    for(int i=0,e=wea.size();i<e;i++)        for(int j=1+c;j<=d;j++)        {            add(po(wea[i].first,j),po(wea[i].second,j-c),Inf);            add(po(wea[i].second,j),po(wea[i].first,j-c),Inf);        }    return dinic()<=w;}int main(){    freopen("cdcq_c.in","r",stdin);    freopen("cdcq_c.out","w",stdout);    n=read();m=read();    w=read();d=read();    s=n*d+1;t=s+1;    for(int i=1;i<=m;i++)        wea.push_back((pr){read(),read()});    for(int i=1;i<=n;i++)        for(int j=1;j<=d;j++)            v[i][j]=read();    int l=0,r=d+1,mid,ans=-1;    while(l<=r)    {        int mid=l+r>>1;        if(judge(mid))            ans=mid,r=mid-1;        else            l=mid+1;    }    printf("%d\n",ans);    return 0;}
原创粉丝点击