hdu 5385 The path 贪心?构造

来源:互联网 发布:淘宝卖家温馨寄语 编辑:程序博客网 时间:2024/06/06 18:44

The path

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 607    Accepted Submission(s): 236
Special Judge


Problem Description
You have a connected directed graph.Let d(x) be the length of the shortest path from 1 to x.Specially d(1)=0.A graph is good if there exist x satisfy d(1)<d(2)<....d(x)>d(x+1)>...d(n).Now you need to set the length of every edge satisfy that the graph is good.Specially,if d(1)<d(2)<..d(n),the graph is good too.

The length of one edge must  [1,n]

It's guaranteed that there exists solution.
 

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains two integers n and m,the number of vertexs and the number of edges.Next m lines contain two integers each, ui and vi (1ui,vin), indicating there is a link between nodes ui and vi and the direction is from ui to vi.

n3105,m6105
1n,m105
 

Output
For each test case,print m lines.The i-th line includes one integer:the length of edge from ui to vi
 

Sample Input
24 61 22 41 31 22 22 34 61 22 31 42 12 12 1
 

Sample Output
122144113444
 

Author
SXYZ
 

Source
2015 Multi-University Training Contest 8
 

Recommend
wange2014
 
d(1)<d(2)<....d(x)>d(x+1)>...d(n),那么所有点的d()可以分为两部分呢,一部分是从的d[1]开始,从小到大,一部分从d[n]开始从小到大
,也可能从d[1]开始从小到大直到d[n]。
因为一定有解,从1开始,一步之内一定有路径通往2或n,然后2一定有路径通往3或n,(如果n可达)n一定有路径通往n-1或前面的。
以这个为顺序表明d(),比如说d[1]标为1,那么如果到了d[2],标为2,如果d[2]不能到3只能到n,那么d[n]=3,n绝对可以到3或n-1中的一个
,标为4,直到把所有点的dis[]标完,两头向中间夹。
ps:如果现在为点2,(且dis[2]已标为2,dis[1]标为了1),点2出发可以到3和5,那么下一个拓展3,把3标为3,而不是拓展5,下一个准备标记dis[]的是4或n,
这两个至少一个可以通过现在的点到达。
标记完后,因为之前用vis,记录了某些点访问过没,我们标记时走过的边长度为边上两点dis[]之差,还有些没有走过的边,
直接标为n(最大长度),不然可能会破坏我们设计好的dis[]顺序性。
比如说:左边从1到x,右边从n到x,标记完了。
    现在x的dis[]最大,从3到x有条边,但是到3之后没有选择标x,而是选择标其他的,然后通过其他的路到x,这个时候如果把这条边随便标为1、2、3之类的
可能dis[x]就比其他一些dis[]小了(本应最大)。(按照我们的标法,最大dis[]为n,所以这条边标为n就可以认为是无穷,就相当于没有从3到x的路径)

#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<climits>#include<queue>#include<vector>#include<map>#include<sstream>#include<set>#include<stack>#include<utility>#pragma comment(linker, "/STACK:102400000,102400000")#define PI 3.1415926535897932384626#define eps 1e-10#define sqr(x) ((x)*(x))#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)#define  lson   num<<1,le,mid#define rson    num<<1|1,mid+1,ri#define MID   int mid=(le+ri)>>1#define zero(x)((x>0? x:-x)<1e-15)using namespace std;const int INF =0x3f3f3f3f;const int maxn=100000+10    ;const int maxm=100000+10    ;//const int INF=    ;typedef long long ll;const ll inf =1000000000000000;//1e15;//ifstream fin("input.txt");//ofstream fout("output.txt");//fin.close();//fout.close();//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);//by yskysker123int n,m;bool incl[maxm];int u[maxm],v[maxm],nex[maxm];int fir[maxn];bool vis[maxn];int d[maxn];int e_max;inline void add_edge(int s,int t){    int e=e_max++;    u[e]=s;    v[e]=t;    nex[e]=fir[s];    fir[s]=e;}void init(){    e_max=0;    memset(fir,-1,sizeof fir);    memset(vis, 0,sizeof vis);    memset(incl,0,sizeof incl);}int main(){    int T;scanf("%d",&T);    while(T--)    {        int x,y;        scanf("%d%d",&n,&m);        init();        for(int i=0;i<m;i++)        {            scanf("%d%d",&x,&y);            add_edge(x,y);        }        int le=1,ri=n,t=0;        vis[1]=1;        while(le<=ri)        {            if( vis[le] )            {                d[le]=++t;                for(int e=fir[le];~e;e=nex[e])                {                    int y=v[e];                    if(vis[y])  continue;                    vis[y]=1;                    incl[e]=1;                }                le++;            }            if(vis[ri])            {                d[ri]=++t;                for(int e=fir[ri];~e;e=nex[e])                {                    int y=v[e];                    if(vis[y])  continue;                    vis[y]=1;                    incl[e]=1;                }                ri--;            }        }        for(int e=0;e<m;e++)        {            if(incl[e])            {                int x=u[e];                int y=v[e];                  printf("%d\n",abs(d[x]-d[y]));            }            else            {                printf("%d\n",n);            }        }    }    return 0;}




0 0
原创粉丝点击